ActivityManagerService.java revision 4590e52f3d0558e01322fe4dd55bb612afdfb079
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.os.BatteryStats;
36import android.util.ArrayMap;
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65
66import libcore.io.IoUtils;
67
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlPullParserException;
70import org.xmlpull.v1.XmlSerializer;
71
72import android.app.Activity;
73import android.app.ActivityManager;
74import android.app.ActivityManager.RunningTaskInfo;
75import android.app.ActivityManager.StackInfo;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    boolean mStartRunning = false;
803    ComponentName mTopComponent;
804    String mTopAction;
805    String mTopData;
806    boolean mProcessesReady = false;
807    boolean mSystemReady = false;
808    boolean mBooting = false;
809    boolean mWaitingUpdate = false;
810    boolean mDidUpdate = false;
811    boolean mOnBattery = false;
812    boolean mLaunchWarningShown = false;
813
814    Context mContext;
815
816    int mFactoryTest;
817
818    boolean mCheckedForSetup;
819
820    /**
821     * The time at which we will allow normal application switches again,
822     * after a call to {@link #stopAppSwitches()}.
823     */
824    long mAppSwitchesAllowedTime;
825
826    /**
827     * This is set to true after the first switch after mAppSwitchesAllowedTime
828     * is set; any switches after that will clear the time.
829     */
830    boolean mDidAppSwitch;
831
832    /**
833     * Last time (in realtime) at which we checked for power usage.
834     */
835    long mLastPowerCheckRealtime;
836
837    /**
838     * Last time (in uptime) at which we checked for power usage.
839     */
840    long mLastPowerCheckUptime;
841
842    /**
843     * Set while we are wanting to sleep, to prevent any
844     * activities from being started/resumed.
845     */
846    boolean mSleeping = false;
847
848    /**
849     * State of external calls telling us if the device is asleep.
850     */
851    boolean mWentToSleep = false;
852
853    /**
854     * State of external call telling us if the lock screen is shown.
855     */
856    boolean mLockScreenShown = false;
857
858    /**
859     * Set if we are shutting down the system, similar to sleeping.
860     */
861    boolean mShuttingDown = false;
862
863    /**
864     * Current sequence id for oom_adj computation traversal.
865     */
866    int mAdjSeq = 0;
867
868    /**
869     * Current sequence id for process LRU updating.
870     */
871    int mLruSeq = 0;
872
873    /**
874     * Keep track of the non-cached/empty process we last found, to help
875     * determine how to distribute cached/empty processes next time.
876     */
877    int mNumNonCachedProcs = 0;
878
879    /**
880     * Keep track of the number of cached hidden procs, to balance oom adj
881     * distribution between those and empty procs.
882     */
883    int mNumCachedHiddenProcs = 0;
884
885    /**
886     * Keep track of the number of service processes we last found, to
887     * determine on the next iteration which should be B services.
888     */
889    int mNumServiceProcs = 0;
890    int mNewNumAServiceProcs = 0;
891    int mNewNumServiceProcs = 0;
892
893    /**
894     * Allow the current computed overall memory level of the system to go down?
895     * This is set to false when we are killing processes for reasons other than
896     * memory management, so that the now smaller process list will not be taken as
897     * an indication that memory is tighter.
898     */
899    boolean mAllowLowerMemLevel = false;
900
901    /**
902     * The last computed memory level, for holding when we are in a state that
903     * processes are going away for other reasons.
904     */
905    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
906
907    /**
908     * The last total number of process we have, to determine if changes actually look
909     * like a shrinking number of process due to lower RAM.
910     */
911    int mLastNumProcesses;
912
913    /**
914     * The uptime of the last time we performed idle maintenance.
915     */
916    long mLastIdleTime = SystemClock.uptimeMillis();
917
918    /**
919     * Total time spent with RAM that has been added in the past since the last idle time.
920     */
921    long mLowRamTimeSinceLastIdle = 0;
922
923    /**
924     * If RAM is currently low, when that horrible situation started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * For reporting to battery stats the current top application.
930     */
931    private String mCurResumedPackage = null;
932    private int mCurResumedUid = -1;
933
934    /**
935     * For reporting to battery stats the apps currently running foreground
936     * service.  The ProcessMap is package/uid tuples; each of these contain
937     * an array of the currently foreground processes.
938     */
939    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
940            = new ProcessMap<ArrayList<ProcessRecord>>();
941
942    /**
943     * This is set if we had to do a delayed dexopt of an app before launching
944     * it, to increasing the ANR timeouts in that case.
945     */
946    boolean mDidDexOpt;
947
948    String mDebugApp = null;
949    boolean mWaitForDebugger = false;
950    boolean mDebugTransient = false;
951    String mOrigDebugApp = null;
952    boolean mOrigWaitForDebugger = false;
953    boolean mAlwaysFinishActivities = false;
954    IActivityController mController = null;
955    String mProfileApp = null;
956    ProcessRecord mProfileProc = null;
957    String mProfileFile;
958    ParcelFileDescriptor mProfileFd;
959    int mProfileType = 0;
960    boolean mAutoStopProfiler = false;
961    String mOpenGlTraceApp = null;
962
963    static class ProcessChangeItem {
964        static final int CHANGE_ACTIVITIES = 1<<0;
965        static final int CHANGE_IMPORTANCE= 1<<1;
966        int changes;
967        int uid;
968        int pid;
969        int importance;
970        boolean foregroundActivities;
971    }
972
973    final RemoteCallbackList<IProcessObserver> mProcessObservers
974            = new RemoteCallbackList<IProcessObserver>();
975    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
976
977    final ArrayList<ProcessChangeItem> mPendingProcessChanges
978            = new ArrayList<ProcessChangeItem>();
979    final ArrayList<ProcessChangeItem> mAvailProcessChanges
980            = new ArrayList<ProcessChangeItem>();
981
982    /**
983     * Runtime CPU use collection thread.  This object's lock is used to
984     * protect all related state.
985     */
986    final Thread mProcessCpuThread;
987
988    /**
989     * Used to collect process stats when showing not responding dialog.
990     * Protected by mProcessCpuThread.
991     */
992    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
993            MONITOR_THREAD_CPU_USAGE);
994    final AtomicLong mLastCpuTime = new AtomicLong(0);
995    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
996
997    long mLastWriteTime = 0;
998
999    /**
1000     * Used to retain an update lock when the foreground activity is in
1001     * immersive mode.
1002     */
1003    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1004
1005    /**
1006     * Set to true after the system has finished booting.
1007     */
1008    boolean mBooted = false;
1009
1010    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1011    int mProcessLimitOverride = -1;
1012
1013    WindowManagerService mWindowManager;
1014
1015    final ActivityThread mSystemThread;
1016
1017    int mCurrentUserId = 0;
1018    int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack
1019    private UserManagerService mUserManager;
1020
1021    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1022        final ProcessRecord mApp;
1023        final int mPid;
1024        final IApplicationThread mAppThread;
1025
1026        AppDeathRecipient(ProcessRecord app, int pid,
1027                IApplicationThread thread) {
1028            if (localLOGV) Slog.v(
1029                TAG, "New death recipient " + this
1030                + " for thread " + thread.asBinder());
1031            mApp = app;
1032            mPid = pid;
1033            mAppThread = thread;
1034        }
1035
1036        @Override
1037        public void binderDied() {
1038            if (localLOGV) Slog.v(
1039                TAG, "Death received in " + this
1040                + " for thread " + mAppThread.asBinder());
1041            synchronized(ActivityManagerService.this) {
1042                appDiedLocked(mApp, mPid, mAppThread);
1043            }
1044        }
1045    }
1046
1047    static final int SHOW_ERROR_MSG = 1;
1048    static final int SHOW_NOT_RESPONDING_MSG = 2;
1049    static final int SHOW_FACTORY_ERROR_MSG = 3;
1050    static final int UPDATE_CONFIGURATION_MSG = 4;
1051    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1052    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1053    static final int SERVICE_TIMEOUT_MSG = 12;
1054    static final int UPDATE_TIME_ZONE = 13;
1055    static final int SHOW_UID_ERROR_MSG = 14;
1056    static final int IM_FEELING_LUCKY_MSG = 15;
1057    static final int PROC_START_TIMEOUT_MSG = 20;
1058    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1059    static final int KILL_APPLICATION_MSG = 22;
1060    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1061    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1062    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1063    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1064    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1065    static final int CLEAR_DNS_CACHE_MSG = 28;
1066    static final int UPDATE_HTTP_PROXY_MSG = 29;
1067    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1068    static final int DISPATCH_PROCESSES_CHANGED = 31;
1069    static final int DISPATCH_PROCESS_DIED = 32;
1070    static final int REPORT_MEM_USAGE_MSG = 33;
1071    static final int REPORT_USER_SWITCH_MSG = 34;
1072    static final int CONTINUE_USER_SWITCH_MSG = 35;
1073    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1074    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1075    static final int PERSIST_URI_GRANTS_MSG = 38;
1076    static final int REQUEST_ALL_PSS_MSG = 39;
1077    static final int START_RELATED_USERS_MSG = 40;
1078    static final int UPDATE_TIME = 41;
1079
1080    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1081    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1082    static final int FIRST_COMPAT_MODE_MSG = 300;
1083    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1084
1085    AlertDialog mUidAlert;
1086    CompatModeDialog mCompatModeDialog;
1087    long mLastMemUsageReportTime = 0;
1088
1089    /**
1090     * Flag whether the current user is a "monkey", i.e. whether
1091     * the UI is driven by a UI automation tool.
1092     */
1093    private boolean mUserIsMonkey;
1094
1095    final ServiceThread mHandlerThread;
1096    final MainHandler mHandler;
1097
1098    final class MainHandler extends Handler {
1099        public MainHandler(Looper looper) {
1100            super(looper, null, true);
1101        }
1102
1103        @Override
1104        public void handleMessage(Message msg) {
1105            switch (msg.what) {
1106            case SHOW_ERROR_MSG: {
1107                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1108                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1109                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1110                synchronized (ActivityManagerService.this) {
1111                    ProcessRecord proc = (ProcessRecord)data.get("app");
1112                    AppErrorResult res = (AppErrorResult) data.get("result");
1113                    if (proc != null && proc.crashDialog != null) {
1114                        Slog.e(TAG, "App already has crash dialog: " + proc);
1115                        if (res != null) {
1116                            res.set(0);
1117                        }
1118                        return;
1119                    }
1120                    if (!showBackground && UserHandle.getAppId(proc.uid)
1121                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1122                            && proc.pid != MY_PID) {
1123                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1124                        if (res != null) {
1125                            res.set(0);
1126                        }
1127                        return;
1128                    }
1129                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1130                        Dialog d = new AppErrorDialog(mContext,
1131                                ActivityManagerService.this, res, proc);
1132                        d.show();
1133                        proc.crashDialog = d;
1134                    } else {
1135                        // The device is asleep, so just pretend that the user
1136                        // saw a crash dialog and hit "force quit".
1137                        if (res != null) {
1138                            res.set(0);
1139                        }
1140                    }
1141                }
1142
1143                ensureBootCompleted();
1144            } break;
1145            case SHOW_NOT_RESPONDING_MSG: {
1146                synchronized (ActivityManagerService.this) {
1147                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1148                    ProcessRecord proc = (ProcessRecord)data.get("app");
1149                    if (proc != null && proc.anrDialog != null) {
1150                        Slog.e(TAG, "App already has anr dialog: " + proc);
1151                        return;
1152                    }
1153
1154                    Intent intent = new Intent("android.intent.action.ANR");
1155                    if (!mProcessesReady) {
1156                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1157                                | Intent.FLAG_RECEIVER_FOREGROUND);
1158                    }
1159                    broadcastIntentLocked(null, null, intent,
1160                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1161                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1162
1163                    if (mShowDialogs) {
1164                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1165                                mContext, proc, (ActivityRecord)data.get("activity"),
1166                                msg.arg1 != 0);
1167                        d.show();
1168                        proc.anrDialog = d;
1169                    } else {
1170                        // Just kill the app if there is no dialog to be shown.
1171                        killAppAtUsersRequest(proc, null);
1172                    }
1173                }
1174
1175                ensureBootCompleted();
1176            } break;
1177            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                synchronized (ActivityManagerService.this) {
1180                    ProcessRecord proc = (ProcessRecord) data.get("app");
1181                    if (proc == null) {
1182                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1183                        break;
1184                    }
1185                    if (proc.crashDialog != null) {
1186                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1187                        return;
1188                    }
1189                    AppErrorResult res = (AppErrorResult) data.get("result");
1190                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1191                        Dialog d = new StrictModeViolationDialog(mContext,
1192                                ActivityManagerService.this, res, proc);
1193                        d.show();
1194                        proc.crashDialog = d;
1195                    } else {
1196                        // The device is asleep, so just pretend that the user
1197                        // saw a crash dialog and hit "force quit".
1198                        res.set(0);
1199                    }
1200                }
1201                ensureBootCompleted();
1202            } break;
1203            case SHOW_FACTORY_ERROR_MSG: {
1204                Dialog d = new FactoryErrorDialog(
1205                    mContext, msg.getData().getCharSequence("msg"));
1206                d.show();
1207                ensureBootCompleted();
1208            } break;
1209            case UPDATE_CONFIGURATION_MSG: {
1210                final ContentResolver resolver = mContext.getContentResolver();
1211                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1212            } break;
1213            case GC_BACKGROUND_PROCESSES_MSG: {
1214                synchronized (ActivityManagerService.this) {
1215                    performAppGcsIfAppropriateLocked();
1216                }
1217            } break;
1218            case WAIT_FOR_DEBUGGER_MSG: {
1219                synchronized (ActivityManagerService.this) {
1220                    ProcessRecord app = (ProcessRecord)msg.obj;
1221                    if (msg.arg1 != 0) {
1222                        if (!app.waitedForDebugger) {
1223                            Dialog d = new AppWaitingForDebuggerDialog(
1224                                    ActivityManagerService.this,
1225                                    mContext, app);
1226                            app.waitDialog = d;
1227                            app.waitedForDebugger = true;
1228                            d.show();
1229                        }
1230                    } else {
1231                        if (app.waitDialog != null) {
1232                            app.waitDialog.dismiss();
1233                            app.waitDialog = null;
1234                        }
1235                    }
1236                }
1237            } break;
1238            case SERVICE_TIMEOUT_MSG: {
1239                if (mDidDexOpt) {
1240                    mDidDexOpt = false;
1241                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1242                    nmsg.obj = msg.obj;
1243                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1244                    return;
1245                }
1246                mServices.serviceTimeout((ProcessRecord)msg.obj);
1247            } break;
1248            case UPDATE_TIME_ZONE: {
1249                synchronized (ActivityManagerService.this) {
1250                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1251                        ProcessRecord r = mLruProcesses.get(i);
1252                        if (r.thread != null) {
1253                            try {
1254                                r.thread.updateTimeZone();
1255                            } catch (RemoteException ex) {
1256                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1257                            }
1258                        }
1259                    }
1260                }
1261            } break;
1262            case CLEAR_DNS_CACHE_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1265                        ProcessRecord r = mLruProcesses.get(i);
1266                        if (r.thread != null) {
1267                            try {
1268                                r.thread.clearDnsCache();
1269                            } catch (RemoteException ex) {
1270                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1271                            }
1272                        }
1273                    }
1274                }
1275            } break;
1276            case UPDATE_HTTP_PROXY_MSG: {
1277                ProxyProperties proxy = (ProxyProperties)msg.obj;
1278                String host = "";
1279                String port = "";
1280                String exclList = "";
1281                String pacFileUrl = null;
1282                if (proxy != null) {
1283                    host = proxy.getHost();
1284                    port = Integer.toString(proxy.getPort());
1285                    exclList = proxy.getExclusionList();
1286                    pacFileUrl = proxy.getPacFileUrl();
1287                }
1288                synchronized (ActivityManagerService.this) {
1289                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1290                        ProcessRecord r = mLruProcesses.get(i);
1291                        if (r.thread != null) {
1292                            try {
1293                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1294                            } catch (RemoteException ex) {
1295                                Slog.w(TAG, "Failed to update http proxy for: " +
1296                                        r.info.processName);
1297                            }
1298                        }
1299                    }
1300                }
1301            } break;
1302            case SHOW_UID_ERROR_MSG: {
1303                String title = "System UIDs Inconsistent";
1304                String text = "UIDs on the system are inconsistent, you need to wipe your"
1305                        + " data partition or your device will be unstable.";
1306                Log.e(TAG, title + ": " + text);
1307                if (mShowDialogs) {
1308                    // XXX This is a temporary dialog, no need to localize.
1309                    AlertDialog d = new BaseErrorDialog(mContext);
1310                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1311                    d.setCancelable(false);
1312                    d.setTitle(title);
1313                    d.setMessage(text);
1314                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1315                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1316                    mUidAlert = d;
1317                    d.show();
1318                }
1319            } break;
1320            case IM_FEELING_LUCKY_MSG: {
1321                if (mUidAlert != null) {
1322                    mUidAlert.dismiss();
1323                    mUidAlert = null;
1324                }
1325            } break;
1326            case PROC_START_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1332                    return;
1333                }
1334                ProcessRecord app = (ProcessRecord)msg.obj;
1335                synchronized (ActivityManagerService.this) {
1336                    processStartTimedOutLocked(app);
1337                }
1338            } break;
1339            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1340                synchronized (ActivityManagerService.this) {
1341                    doPendingActivityLaunchesLocked(true);
1342                }
1343            } break;
1344            case KILL_APPLICATION_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    int appid = msg.arg1;
1347                    boolean restart = (msg.arg2 == 1);
1348                    Bundle bundle = (Bundle)msg.obj;
1349                    String pkg = bundle.getString("pkg");
1350                    String reason = bundle.getString("reason");
1351                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1352                            false, UserHandle.USER_ALL, reason);
1353                }
1354            } break;
1355            case FINALIZE_PENDING_INTENT_MSG: {
1356                ((PendingIntentRecord)msg.obj).completeFinalize();
1357            } break;
1358            case POST_HEAVY_NOTIFICATION_MSG: {
1359                INotificationManager inm = NotificationManager.getService();
1360                if (inm == null) {
1361                    return;
1362                }
1363
1364                ActivityRecord root = (ActivityRecord)msg.obj;
1365                ProcessRecord process = root.app;
1366                if (process == null) {
1367                    return;
1368                }
1369
1370                try {
1371                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1372                    String text = mContext.getString(R.string.heavy_weight_notification,
1373                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1374                    Notification notification = new Notification();
1375                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1376                    notification.when = 0;
1377                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1378                    notification.tickerText = text;
1379                    notification.defaults = 0; // please be quiet
1380                    notification.sound = null;
1381                    notification.vibrate = null;
1382                    notification.setLatestEventInfo(context, text,
1383                            mContext.getText(R.string.heavy_weight_notification_detail),
1384                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1385                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1386                                    new UserHandle(root.userId)));
1387
1388                    try {
1389                        int[] outId = new int[1];
1390                        inm.enqueueNotificationWithTag("android", "android", null,
1391                                R.string.heavy_weight_notification,
1392                                notification, outId, root.userId);
1393                    } catch (RuntimeException e) {
1394                        Slog.w(ActivityManagerService.TAG,
1395                                "Error showing notification for heavy-weight app", e);
1396                    } catch (RemoteException e) {
1397                    }
1398                } catch (NameNotFoundException e) {
1399                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1400                }
1401            } break;
1402            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1403                INotificationManager inm = NotificationManager.getService();
1404                if (inm == null) {
1405                    return;
1406                }
1407                try {
1408                    inm.cancelNotificationWithTag("android", null,
1409                            R.string.heavy_weight_notification,  msg.arg1);
1410                } catch (RuntimeException e) {
1411                    Slog.w(ActivityManagerService.TAG,
1412                            "Error canceling notification for service", e);
1413                } catch (RemoteException e) {
1414                }
1415            } break;
1416            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1417                synchronized (ActivityManagerService.this) {
1418                    checkExcessivePowerUsageLocked(true);
1419                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1420                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1421                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1422                }
1423            } break;
1424            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    ActivityRecord ar = (ActivityRecord)msg.obj;
1427                    if (mCompatModeDialog != null) {
1428                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1429                                ar.info.applicationInfo.packageName)) {
1430                            return;
1431                        }
1432                        mCompatModeDialog.dismiss();
1433                        mCompatModeDialog = null;
1434                    }
1435                    if (ar != null && false) {
1436                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1437                                ar.packageName)) {
1438                            int mode = mCompatModePackages.computeCompatModeLocked(
1439                                    ar.info.applicationInfo);
1440                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1441                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1442                                mCompatModeDialog = new CompatModeDialog(
1443                                        ActivityManagerService.this, mContext,
1444                                        ar.info.applicationInfo);
1445                                mCompatModeDialog.show();
1446                            }
1447                        }
1448                    }
1449                }
1450                break;
1451            }
1452            case DISPATCH_PROCESSES_CHANGED: {
1453                dispatchProcessesChanged();
1454                break;
1455            }
1456            case DISPATCH_PROCESS_DIED: {
1457                final int pid = msg.arg1;
1458                final int uid = msg.arg2;
1459                dispatchProcessDied(pid, uid);
1460                break;
1461            }
1462            case REPORT_MEM_USAGE_MSG: {
1463                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1464                Thread thread = new Thread() {
1465                    @Override public void run() {
1466                        final SparseArray<ProcessMemInfo> infoMap
1467                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1468                        for (int i=0, N=memInfos.size(); i<N; i++) {
1469                            ProcessMemInfo mi = memInfos.get(i);
1470                            infoMap.put(mi.pid, mi);
1471                        }
1472                        updateCpuStatsNow();
1473                        synchronized (mProcessCpuThread) {
1474                            final int N = mProcessCpuTracker.countStats();
1475                            for (int i=0; i<N; i++) {
1476                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1477                                if (st.vsize > 0) {
1478                                    long pss = Debug.getPss(st.pid, null);
1479                                    if (pss > 0) {
1480                                        if (infoMap.indexOfKey(st.pid) < 0) {
1481                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1482                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1483                                            mi.pss = pss;
1484                                            memInfos.add(mi);
1485                                        }
1486                                    }
1487                                }
1488                            }
1489                        }
1490
1491                        long totalPss = 0;
1492                        for (int i=0, N=memInfos.size(); i<N; i++) {
1493                            ProcessMemInfo mi = memInfos.get(i);
1494                            if (mi.pss == 0) {
1495                                mi.pss = Debug.getPss(mi.pid, null);
1496                            }
1497                            totalPss += mi.pss;
1498                        }
1499                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1500                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1501                                if (lhs.oomAdj != rhs.oomAdj) {
1502                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1503                                }
1504                                if (lhs.pss != rhs.pss) {
1505                                    return lhs.pss < rhs.pss ? 1 : -1;
1506                                }
1507                                return 0;
1508                            }
1509                        });
1510
1511                        StringBuilder tag = new StringBuilder(128);
1512                        StringBuilder stack = new StringBuilder(128);
1513                        tag.append("Low on memory -- ");
1514                        appendMemBucket(tag, totalPss, "total", false);
1515                        appendMemBucket(stack, totalPss, "total", true);
1516
1517                        StringBuilder logBuilder = new StringBuilder(1024);
1518                        logBuilder.append("Low on memory:\n");
1519
1520                        boolean firstLine = true;
1521                        int lastOomAdj = Integer.MIN_VALUE;
1522                        for (int i=0, N=memInfos.size(); i<N; i++) {
1523                            ProcessMemInfo mi = memInfos.get(i);
1524
1525                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1526                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1527                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1528                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1529                                if (lastOomAdj != mi.oomAdj) {
1530                                    lastOomAdj = mi.oomAdj;
1531                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1532                                        tag.append(" / ");
1533                                    }
1534                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1535                                        if (firstLine) {
1536                                            stack.append(":");
1537                                            firstLine = false;
1538                                        }
1539                                        stack.append("\n\t at ");
1540                                    } else {
1541                                        stack.append("$");
1542                                    }
1543                                } else {
1544                                    tag.append(" ");
1545                                    stack.append("$");
1546                                }
1547                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1548                                    appendMemBucket(tag, mi.pss, mi.name, false);
1549                                }
1550                                appendMemBucket(stack, mi.pss, mi.name, true);
1551                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1552                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1553                                    stack.append("(");
1554                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1555                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1556                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1557                                            stack.append(":");
1558                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1559                                        }
1560                                    }
1561                                    stack.append(")");
1562                                }
1563                            }
1564
1565                            logBuilder.append("  ");
1566                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1567                            logBuilder.append(' ');
1568                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1569                            logBuilder.append(' ');
1570                            ProcessList.appendRamKb(logBuilder, mi.pss);
1571                            logBuilder.append(" kB: ");
1572                            logBuilder.append(mi.name);
1573                            logBuilder.append(" (");
1574                            logBuilder.append(mi.pid);
1575                            logBuilder.append(") ");
1576                            logBuilder.append(mi.adjType);
1577                            logBuilder.append('\n');
1578                            if (mi.adjReason != null) {
1579                                logBuilder.append("                      ");
1580                                logBuilder.append(mi.adjReason);
1581                                logBuilder.append('\n');
1582                            }
1583                        }
1584
1585                        logBuilder.append("           ");
1586                        ProcessList.appendRamKb(logBuilder, totalPss);
1587                        logBuilder.append(" kB: TOTAL\n");
1588
1589                        long[] infos = new long[Debug.MEMINFO_COUNT];
1590                        Debug.getMemInfo(infos);
1591                        logBuilder.append("  MemInfo: ");
1592                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1594                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1595                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1596                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1597                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1598                            logBuilder.append("  ZRAM: ");
1599                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1600                            logBuilder.append(" kB RAM, ");
1601                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1602                            logBuilder.append(" kB swap total, ");
1603                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1604                            logBuilder.append(" kB swap free\n");
1605                        }
1606                        Slog.i(TAG, logBuilder.toString());
1607
1608                        StringBuilder dropBuilder = new StringBuilder(1024);
1609                        /*
1610                        StringWriter oomSw = new StringWriter();
1611                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1612                        StringWriter catSw = new StringWriter();
1613                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1614                        String[] emptyArgs = new String[] { };
1615                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1616                        oomPw.flush();
1617                        String oomString = oomSw.toString();
1618                        */
1619                        dropBuilder.append(stack);
1620                        dropBuilder.append('\n');
1621                        dropBuilder.append('\n');
1622                        dropBuilder.append(logBuilder);
1623                        dropBuilder.append('\n');
1624                        /*
1625                        dropBuilder.append(oomString);
1626                        dropBuilder.append('\n');
1627                        */
1628                        StringWriter catSw = new StringWriter();
1629                        synchronized (ActivityManagerService.this) {
1630                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1631                            String[] emptyArgs = new String[] { };
1632                            catPw.println();
1633                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1634                            catPw.println();
1635                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1636                                    false, false, null);
1637                            catPw.println();
1638                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1639                            catPw.flush();
1640                        }
1641                        dropBuilder.append(catSw.toString());
1642                        addErrorToDropBox("lowmem", null, "system_server", null,
1643                                null, tag.toString(), dropBuilder.toString(), null, null);
1644                        //Slog.i(TAG, "Sent to dropbox:");
1645                        //Slog.i(TAG, dropBuilder.toString());
1646                        synchronized (ActivityManagerService.this) {
1647                            long now = SystemClock.uptimeMillis();
1648                            if (mLastMemUsageReportTime < now) {
1649                                mLastMemUsageReportTime = now;
1650                            }
1651                        }
1652                    }
1653                };
1654                thread.start();
1655                break;
1656            }
1657            case REPORT_USER_SWITCH_MSG: {
1658                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1659                break;
1660            }
1661            case CONTINUE_USER_SWITCH_MSG: {
1662                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1663                break;
1664            }
1665            case USER_SWITCH_TIMEOUT_MSG: {
1666                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1667                break;
1668            }
1669            case IMMERSIVE_MODE_LOCK_MSG: {
1670                final boolean nextState = (msg.arg1 != 0);
1671                if (mUpdateLock.isHeld() != nextState) {
1672                    if (DEBUG_IMMERSIVE) {
1673                        final ActivityRecord r = (ActivityRecord) msg.obj;
1674                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1675                    }
1676                    if (nextState) {
1677                        mUpdateLock.acquire();
1678                    } else {
1679                        mUpdateLock.release();
1680                    }
1681                }
1682                break;
1683            }
1684            case PERSIST_URI_GRANTS_MSG: {
1685                writeGrantedUriPermissions();
1686                break;
1687            }
1688            case REQUEST_ALL_PSS_MSG: {
1689                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1690                break;
1691            }
1692            case START_RELATED_USERS_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    startRelatedUsersLocked();
1695                }
1696                break;
1697            }
1698            case UPDATE_TIME: {
1699                synchronized (ActivityManagerService.this) {
1700                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1701                        ProcessRecord r = mLruProcesses.get(i);
1702                        if (r.thread != null) {
1703                            try {
1704                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1705                            } catch (RemoteException ex) {
1706                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1707                            }
1708                        }
1709                    }
1710                }
1711                break;
1712            }
1713            }
1714        }
1715    };
1716
1717    static final int COLLECT_PSS_BG_MSG = 1;
1718
1719    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1720        @Override
1721        public void handleMessage(Message msg) {
1722            switch (msg.what) {
1723            case COLLECT_PSS_BG_MSG: {
1724                int i=0, num=0;
1725                long start = SystemClock.uptimeMillis();
1726                long[] tmp = new long[1];
1727                do {
1728                    ProcessRecord proc;
1729                    int procState;
1730                    int pid;
1731                    synchronized (ActivityManagerService.this) {
1732                        if (i >= mPendingPssProcesses.size()) {
1733                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1734                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1735                            mPendingPssProcesses.clear();
1736                            return;
1737                        }
1738                        proc = mPendingPssProcesses.get(i);
1739                        procState = proc.pssProcState;
1740                        if (proc.thread != null && procState == proc.setProcState) {
1741                            pid = proc.pid;
1742                        } else {
1743                            proc = null;
1744                            pid = 0;
1745                        }
1746                        i++;
1747                    }
1748                    if (proc != null) {
1749                        long pss = Debug.getPss(pid, tmp);
1750                        synchronized (ActivityManagerService.this) {
1751                            if (proc.thread != null && proc.setProcState == procState
1752                                    && proc.pid == pid) {
1753                                num++;
1754                                proc.lastPssTime = SystemClock.uptimeMillis();
1755                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1756                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1757                                        + ": " + pss + " lastPss=" + proc.lastPss
1758                                        + " state=" + ProcessList.makeProcStateString(procState));
1759                                if (proc.initialIdlePss == 0) {
1760                                    proc.initialIdlePss = pss;
1761                                }
1762                                proc.lastPss = pss;
1763                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1764                                    proc.lastCachedPss = pss;
1765                                }
1766                            }
1767                        }
1768                    }
1769                } while (true);
1770            }
1771            }
1772        }
1773    };
1774
1775    public void setSystemProcess() {
1776        try {
1777            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1778            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1779            ServiceManager.addService("meminfo", new MemBinder(this));
1780            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1781            ServiceManager.addService("dbinfo", new DbBinder(this));
1782            if (MONITOR_CPU_USAGE) {
1783                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1784            }
1785            ServiceManager.addService("permission", new PermissionController(this));
1786
1787            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1788                    "android", STOCK_PM_FLAGS);
1789            mSystemThread.installSystemApplicationInfo(info);
1790
1791            synchronized (this) {
1792                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1793                app.persistent = true;
1794                app.pid = MY_PID;
1795                app.maxAdj = ProcessList.SYSTEM_ADJ;
1796                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1797                mProcessNames.put(app.processName, app.uid, app);
1798                synchronized (mPidsSelfLocked) {
1799                    mPidsSelfLocked.put(app.pid, app);
1800                }
1801                updateLruProcessLocked(app, false, null);
1802                updateOomAdjLocked();
1803            }
1804        } catch (PackageManager.NameNotFoundException e) {
1805            throw new RuntimeException(
1806                    "Unable to find android system package", e);
1807        }
1808    }
1809
1810    public void setWindowManager(WindowManagerService wm) {
1811        mWindowManager = wm;
1812        mStackSupervisor.setWindowManager(wm);
1813    }
1814
1815    public void startObservingNativeCrashes() {
1816        final NativeCrashListener ncl = new NativeCrashListener(this);
1817        ncl.start();
1818    }
1819
1820    public IAppOpsService getAppOpsService() {
1821        return mAppOpsService;
1822    }
1823
1824    static class MemBinder extends Binder {
1825        ActivityManagerService mActivityManagerService;
1826        MemBinder(ActivityManagerService activityManagerService) {
1827            mActivityManagerService = activityManagerService;
1828        }
1829
1830        @Override
1831        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1832            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1833                    != PackageManager.PERMISSION_GRANTED) {
1834                pw.println("Permission Denial: can't dump meminfo from from pid="
1835                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1836                        + " without permission " + android.Manifest.permission.DUMP);
1837                return;
1838            }
1839
1840            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1841        }
1842    }
1843
1844    static class GraphicsBinder extends Binder {
1845        ActivityManagerService mActivityManagerService;
1846        GraphicsBinder(ActivityManagerService activityManagerService) {
1847            mActivityManagerService = activityManagerService;
1848        }
1849
1850        @Override
1851        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1852            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1853                    != PackageManager.PERMISSION_GRANTED) {
1854                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1855                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1856                        + " without permission " + android.Manifest.permission.DUMP);
1857                return;
1858            }
1859
1860            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1861        }
1862    }
1863
1864    static class DbBinder extends Binder {
1865        ActivityManagerService mActivityManagerService;
1866        DbBinder(ActivityManagerService activityManagerService) {
1867            mActivityManagerService = activityManagerService;
1868        }
1869
1870        @Override
1871        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1872            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1873                    != PackageManager.PERMISSION_GRANTED) {
1874                pw.println("Permission Denial: can't dump dbinfo from from pid="
1875                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1876                        + " without permission " + android.Manifest.permission.DUMP);
1877                return;
1878            }
1879
1880            mActivityManagerService.dumpDbInfo(fd, pw, args);
1881        }
1882    }
1883
1884    static class CpuBinder extends Binder {
1885        ActivityManagerService mActivityManagerService;
1886        CpuBinder(ActivityManagerService activityManagerService) {
1887            mActivityManagerService = activityManagerService;
1888        }
1889
1890        @Override
1891        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1892            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1893                    != PackageManager.PERMISSION_GRANTED) {
1894                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1895                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1896                        + " without permission " + android.Manifest.permission.DUMP);
1897                return;
1898            }
1899
1900            synchronized (mActivityManagerService.mProcessCpuThread) {
1901                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1902                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1903                        SystemClock.uptimeMillis()));
1904            }
1905        }
1906    }
1907
1908    public static final class Lifecycle extends SystemService {
1909        private final ActivityManagerService mService;
1910
1911        public Lifecycle(Context context) {
1912            super(context);
1913            mService = new ActivityManagerService(context);
1914        }
1915
1916        @Override
1917        public void onStart() {
1918            mService.start();
1919        }
1920
1921        public ActivityManagerService getService() {
1922            return mService;
1923        }
1924    }
1925
1926    // Note: This method is invoked on the main thread but may need to attach various
1927    // handlers to other threads.  So take care to be explicit about the looper.
1928    public ActivityManagerService(Context systemContext) {
1929        mContext = systemContext;
1930        mFactoryTest = FactoryTest.getMode();
1931        mSystemThread = ActivityThread.currentActivityThread();
1932
1933        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1934
1935        mHandlerThread = new ServiceThread(TAG,
1936                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1937        mHandlerThread.start();
1938        mHandler = new MainHandler(mHandlerThread.getLooper());
1939
1940        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1941                "foreground", BROADCAST_FG_TIMEOUT, false);
1942        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1943                "background", BROADCAST_BG_TIMEOUT, true);
1944        mBroadcastQueues[0] = mFgBroadcastQueue;
1945        mBroadcastQueues[1] = mBgBroadcastQueue;
1946
1947        mServices = new ActiveServices(this);
1948        mProviderMap = new ProviderMap(this);
1949
1950        // TODO: Move creation of battery stats service outside of activity manager service.
1951        File dataDir = Environment.getDataDirectory();
1952        File systemDir = new File(dataDir, "system");
1953        systemDir.mkdirs();
1954        mBatteryStatsService = new BatteryStatsService(new File(
1955                systemDir, "batterystats.bin").toString(), mHandler);
1956        mBatteryStatsService.getActiveStatistics().readLocked();
1957        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1958        mOnBattery = DEBUG_POWER ? true
1959                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1960        mBatteryStatsService.getActiveStatistics().setCallback(this);
1961
1962        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1963
1964        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1965        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1966
1967        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1968
1969        // User 0 is the first and only user that runs at boot.
1970        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1971        mUserLru.add(Integer.valueOf(0));
1972        updateStartedUserArrayLocked();
1973
1974        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1975            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1976
1977        mConfiguration.setToDefaults();
1978        mConfiguration.setLocale(Locale.getDefault());
1979
1980        mConfigurationSeq = mConfiguration.seq = 1;
1981        mProcessCpuTracker.init();
1982
1983        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1984        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1985        mStackSupervisor = new ActivityStackSupervisor(this);
1986
1987        mProcessCpuThread = new Thread("CpuTracker") {
1988            @Override
1989            public void run() {
1990                while (true) {
1991                    try {
1992                        try {
1993                            synchronized(this) {
1994                                final long now = SystemClock.uptimeMillis();
1995                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1996                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1997                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1998                                //        + ", write delay=" + nextWriteDelay);
1999                                if (nextWriteDelay < nextCpuDelay) {
2000                                    nextCpuDelay = nextWriteDelay;
2001                                }
2002                                if (nextCpuDelay > 0) {
2003                                    mProcessCpuMutexFree.set(true);
2004                                    this.wait(nextCpuDelay);
2005                                }
2006                            }
2007                        } catch (InterruptedException e) {
2008                        }
2009                        updateCpuStatsNow();
2010                    } catch (Exception e) {
2011                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2012                    }
2013                }
2014            }
2015        };
2016
2017        Watchdog.getInstance().addMonitor(this);
2018        Watchdog.getInstance().addThread(mHandler);
2019    }
2020
2021    private void start() {
2022        mProcessCpuThread.start();
2023
2024        mBatteryStatsService.publish(mContext);
2025        mUsageStatsService.publish(mContext);
2026        mAppOpsService.publish(mContext);
2027        startRunning(null, null, null, null);
2028    }
2029
2030    @Override
2031    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2032            throws RemoteException {
2033        if (code == SYSPROPS_TRANSACTION) {
2034            // We need to tell all apps about the system property change.
2035            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2036            synchronized(this) {
2037                final int NP = mProcessNames.getMap().size();
2038                for (int ip=0; ip<NP; ip++) {
2039                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2040                    final int NA = apps.size();
2041                    for (int ia=0; ia<NA; ia++) {
2042                        ProcessRecord app = apps.valueAt(ia);
2043                        if (app.thread != null) {
2044                            procs.add(app.thread.asBinder());
2045                        }
2046                    }
2047                }
2048            }
2049
2050            int N = procs.size();
2051            for (int i=0; i<N; i++) {
2052                Parcel data2 = Parcel.obtain();
2053                try {
2054                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2055                } catch (RemoteException e) {
2056                }
2057                data2.recycle();
2058            }
2059        }
2060        try {
2061            return super.onTransact(code, data, reply, flags);
2062        } catch (RuntimeException e) {
2063            // The activity manager only throws security exceptions, so let's
2064            // log all others.
2065            if (!(e instanceof SecurityException)) {
2066                Slog.wtf(TAG, "Activity Manager Crash", e);
2067            }
2068            throw e;
2069        }
2070    }
2071
2072    void updateCpuStats() {
2073        final long now = SystemClock.uptimeMillis();
2074        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2075            return;
2076        }
2077        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2078            synchronized (mProcessCpuThread) {
2079                mProcessCpuThread.notify();
2080            }
2081        }
2082    }
2083
2084    void updateCpuStatsNow() {
2085        synchronized (mProcessCpuThread) {
2086            mProcessCpuMutexFree.set(false);
2087            final long now = SystemClock.uptimeMillis();
2088            boolean haveNewCpuStats = false;
2089
2090            if (MONITOR_CPU_USAGE &&
2091                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2092                mLastCpuTime.set(now);
2093                haveNewCpuStats = true;
2094                mProcessCpuTracker.update();
2095                //Slog.i(TAG, mProcessCpu.printCurrentState());
2096                //Slog.i(TAG, "Total CPU usage: "
2097                //        + mProcessCpu.getTotalCpuPercent() + "%");
2098
2099                // Slog the cpu usage if the property is set.
2100                if ("true".equals(SystemProperties.get("events.cpu"))) {
2101                    int user = mProcessCpuTracker.getLastUserTime();
2102                    int system = mProcessCpuTracker.getLastSystemTime();
2103                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2104                    int irq = mProcessCpuTracker.getLastIrqTime();
2105                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2106                    int idle = mProcessCpuTracker.getLastIdleTime();
2107
2108                    int total = user + system + iowait + irq + softIrq + idle;
2109                    if (total == 0) total = 1;
2110
2111                    EventLog.writeEvent(EventLogTags.CPU,
2112                            ((user+system+iowait+irq+softIrq) * 100) / total,
2113                            (user * 100) / total,
2114                            (system * 100) / total,
2115                            (iowait * 100) / total,
2116                            (irq * 100) / total,
2117                            (softIrq * 100) / total);
2118                }
2119            }
2120
2121            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2122            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2123            synchronized(bstats) {
2124                synchronized(mPidsSelfLocked) {
2125                    if (haveNewCpuStats) {
2126                        if (mOnBattery) {
2127                            int perc = bstats.startAddingCpuLocked();
2128                            int totalUTime = 0;
2129                            int totalSTime = 0;
2130                            final int N = mProcessCpuTracker.countStats();
2131                            for (int i=0; i<N; i++) {
2132                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2133                                if (!st.working) {
2134                                    continue;
2135                                }
2136                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2137                                int otherUTime = (st.rel_utime*perc)/100;
2138                                int otherSTime = (st.rel_stime*perc)/100;
2139                                totalUTime += otherUTime;
2140                                totalSTime += otherSTime;
2141                                if (pr != null) {
2142                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2143                                    if (ps == null || !ps.isActive()) {
2144                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2145                                                pr.info.uid, pr.processName);
2146                                    }
2147                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2148                                            st.rel_stime-otherSTime);
2149                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2150                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2151                                } else {
2152                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2153                                    if (ps == null || !ps.isActive()) {
2154                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2155                                                bstats.mapUid(st.uid), st.name);
2156                                    }
2157                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2158                                            st.rel_stime-otherSTime);
2159                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2160                                }
2161                            }
2162                            bstats.finishAddingCpuLocked(perc, totalUTime,
2163                                    totalSTime, cpuSpeedTimes);
2164                        }
2165                    }
2166                }
2167
2168                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2169                    mLastWriteTime = now;
2170                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2171                }
2172            }
2173        }
2174    }
2175
2176    @Override
2177    public void batteryNeedsCpuUpdate() {
2178        updateCpuStatsNow();
2179    }
2180
2181    @Override
2182    public void batteryPowerChanged(boolean onBattery) {
2183        // When plugging in, update the CPU stats first before changing
2184        // the plug state.
2185        updateCpuStatsNow();
2186        synchronized (this) {
2187            synchronized(mPidsSelfLocked) {
2188                mOnBattery = DEBUG_POWER ? true : onBattery;
2189            }
2190        }
2191    }
2192
2193    /**
2194     * Initialize the application bind args. These are passed to each
2195     * process when the bindApplication() IPC is sent to the process. They're
2196     * lazily setup to make sure the services are running when they're asked for.
2197     */
2198    private HashMap<String, IBinder> getCommonServicesLocked() {
2199        if (mAppBindArgs == null) {
2200            mAppBindArgs = new HashMap<String, IBinder>();
2201
2202            // Setup the application init args
2203            mAppBindArgs.put("package", ServiceManager.getService("package"));
2204            mAppBindArgs.put("window", ServiceManager.getService("window"));
2205            mAppBindArgs.put(Context.ALARM_SERVICE,
2206                    ServiceManager.getService(Context.ALARM_SERVICE));
2207        }
2208        return mAppBindArgs;
2209    }
2210
2211    final void setFocusedActivityLocked(ActivityRecord r) {
2212        if (mFocusedActivity != r) {
2213            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2214            mFocusedActivity = r;
2215            mStackSupervisor.setFocusedStack(r);
2216            if (r != null) {
2217                mWindowManager.setFocusedApp(r.appToken, true);
2218            }
2219            applyUpdateLockStateLocked(r);
2220        }
2221    }
2222
2223    @Override
2224    public void setFocusedStack(int stackId) {
2225        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2226        synchronized (ActivityManagerService.this) {
2227            ActivityStack stack = mStackSupervisor.getStack(stackId);
2228            if (stack != null) {
2229                ActivityRecord r = stack.topRunningActivityLocked(null);
2230                if (r != null) {
2231                    setFocusedActivityLocked(r);
2232                }
2233            }
2234        }
2235    }
2236
2237    @Override
2238    public void notifyActivityDrawn(IBinder token) {
2239        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2240        synchronized (this) {
2241            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2242            if (r != null) {
2243                r.task.stack.notifyActivityDrawnLocked(r);
2244            }
2245        }
2246    }
2247
2248    final void applyUpdateLockStateLocked(ActivityRecord r) {
2249        // Modifications to the UpdateLock state are done on our handler, outside
2250        // the activity manager's locks.  The new state is determined based on the
2251        // state *now* of the relevant activity record.  The object is passed to
2252        // the handler solely for logging detail, not to be consulted/modified.
2253        final boolean nextState = r != null && r.immersive;
2254        mHandler.sendMessage(
2255                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2256    }
2257
2258    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2259        Message msg = Message.obtain();
2260        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2261        msg.obj = r.task.askedCompatMode ? null : r;
2262        mHandler.sendMessage(msg);
2263    }
2264
2265    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2266            String what, Object obj, ProcessRecord srcApp) {
2267        app.lastActivityTime = now;
2268
2269        if (app.activities.size() > 0) {
2270            // Don't want to touch dependent processes that are hosting activities.
2271            return index;
2272        }
2273
2274        int lrui = mLruProcesses.lastIndexOf(app);
2275        if (lrui < 0) {
2276            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2277                    + what + " " + obj + " from " + srcApp);
2278            return index;
2279        }
2280
2281        if (lrui >= index) {
2282            // Don't want to cause this to move dependent processes *back* in the
2283            // list as if they were less frequently used.
2284            return index;
2285        }
2286
2287        if (lrui >= mLruProcessActivityStart) {
2288            // Don't want to touch dependent processes that are hosting activities.
2289            return index;
2290        }
2291
2292        mLruProcesses.remove(lrui);
2293        if (index > 0) {
2294            index--;
2295        }
2296        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2297                + " in LRU list: " + app);
2298        mLruProcesses.add(index, app);
2299        return index;
2300    }
2301
2302    final void removeLruProcessLocked(ProcessRecord app) {
2303        int lrui = mLruProcesses.lastIndexOf(app);
2304        if (lrui >= 0) {
2305            if (lrui <= mLruProcessActivityStart) {
2306                mLruProcessActivityStart--;
2307            }
2308            if (lrui <= mLruProcessServiceStart) {
2309                mLruProcessServiceStart--;
2310            }
2311            mLruProcesses.remove(lrui);
2312        }
2313    }
2314
2315    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2316            ProcessRecord client) {
2317        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2318                || app.treatLikeActivity;
2319        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2320        if (!activityChange && hasActivity) {
2321            // The process has activities, so we are only allowing activity-based adjustments
2322            // to move it.  It should be kept in the front of the list with other
2323            // processes that have activities, and we don't want those to change their
2324            // order except due to activity operations.
2325            return;
2326        }
2327
2328        mLruSeq++;
2329        final long now = SystemClock.uptimeMillis();
2330        app.lastActivityTime = now;
2331
2332        // First a quick reject: if the app is already at the position we will
2333        // put it, then there is nothing to do.
2334        if (hasActivity) {
2335            final int N = mLruProcesses.size();
2336            if (N > 0 && mLruProcesses.get(N-1) == app) {
2337                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2338                return;
2339            }
2340        } else {
2341            if (mLruProcessServiceStart > 0
2342                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2343                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2344                return;
2345            }
2346        }
2347
2348        int lrui = mLruProcesses.lastIndexOf(app);
2349
2350        if (app.persistent && lrui >= 0) {
2351            // We don't care about the position of persistent processes, as long as
2352            // they are in the list.
2353            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2354            return;
2355        }
2356
2357        /* In progress: compute new position first, so we can avoid doing work
2358           if the process is not actually going to move.  Not yet working.
2359        int addIndex;
2360        int nextIndex;
2361        boolean inActivity = false, inService = false;
2362        if (hasActivity) {
2363            // Process has activities, put it at the very tipsy-top.
2364            addIndex = mLruProcesses.size();
2365            nextIndex = mLruProcessServiceStart;
2366            inActivity = true;
2367        } else if (hasService) {
2368            // Process has services, put it at the top of the service list.
2369            addIndex = mLruProcessActivityStart;
2370            nextIndex = mLruProcessServiceStart;
2371            inActivity = true;
2372            inService = true;
2373        } else  {
2374            // Process not otherwise of interest, it goes to the top of the non-service area.
2375            addIndex = mLruProcessServiceStart;
2376            if (client != null) {
2377                int clientIndex = mLruProcesses.lastIndexOf(client);
2378                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2379                        + app);
2380                if (clientIndex >= 0 && addIndex > clientIndex) {
2381                    addIndex = clientIndex;
2382                }
2383            }
2384            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2385        }
2386
2387        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2388                + mLruProcessActivityStart + "): " + app);
2389        */
2390
2391        if (lrui >= 0) {
2392            if (lrui < mLruProcessActivityStart) {
2393                mLruProcessActivityStart--;
2394            }
2395            if (lrui < mLruProcessServiceStart) {
2396                mLruProcessServiceStart--;
2397            }
2398            /*
2399            if (addIndex > lrui) {
2400                addIndex--;
2401            }
2402            if (nextIndex > lrui) {
2403                nextIndex--;
2404            }
2405            */
2406            mLruProcesses.remove(lrui);
2407        }
2408
2409        /*
2410        mLruProcesses.add(addIndex, app);
2411        if (inActivity) {
2412            mLruProcessActivityStart++;
2413        }
2414        if (inService) {
2415            mLruProcessActivityStart++;
2416        }
2417        */
2418
2419        int nextIndex;
2420        if (hasActivity) {
2421            final int N = mLruProcesses.size();
2422            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2423                // Process doesn't have activities, but has clients with
2424                // activities...  move it up, but one below the top (the top
2425                // should always have a real activity).
2426                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2427                mLruProcesses.add(N-1, app);
2428                // To keep it from spamming the LRU list (by making a bunch of clients),
2429                // we will push down any other entries owned by the app.
2430                final int uid = app.info.uid;
2431                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2432                    ProcessRecord subProc = mLruProcesses.get(i);
2433                    if (subProc.info.uid == uid) {
2434                        // We want to push this one down the list.  If the process after
2435                        // it is for the same uid, however, don't do so, because we don't
2436                        // want them internally to be re-ordered.
2437                        if (mLruProcesses.get(i-1).info.uid != uid) {
2438                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2439                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2440                            ProcessRecord tmp = mLruProcesses.get(i);
2441                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2442                            mLruProcesses.set(i-1, tmp);
2443                            i--;
2444                        }
2445                    } else {
2446                        // A gap, we can stop here.
2447                        break;
2448                    }
2449                }
2450            } else {
2451                // Process has activities, put it at the very tipsy-top.
2452                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2453                mLruProcesses.add(app);
2454            }
2455            nextIndex = mLruProcessServiceStart;
2456        } else if (hasService) {
2457            // Process has services, put it at the top of the service list.
2458            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2459            mLruProcesses.add(mLruProcessActivityStart, app);
2460            nextIndex = mLruProcessServiceStart;
2461            mLruProcessActivityStart++;
2462        } else  {
2463            // Process not otherwise of interest, it goes to the top of the non-service area.
2464            int index = mLruProcessServiceStart;
2465            if (client != null) {
2466                // If there is a client, don't allow the process to be moved up higher
2467                // in the list than that client.
2468                int clientIndex = mLruProcesses.lastIndexOf(client);
2469                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2470                        + " when updating " + app);
2471                if (clientIndex <= lrui) {
2472                    // Don't allow the client index restriction to push it down farther in the
2473                    // list than it already is.
2474                    clientIndex = lrui;
2475                }
2476                if (clientIndex >= 0 && index > clientIndex) {
2477                    index = clientIndex;
2478                }
2479            }
2480            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2481            mLruProcesses.add(index, app);
2482            nextIndex = index-1;
2483            mLruProcessActivityStart++;
2484            mLruProcessServiceStart++;
2485        }
2486
2487        // If the app is currently using a content provider or service,
2488        // bump those processes as well.
2489        for (int j=app.connections.size()-1; j>=0; j--) {
2490            ConnectionRecord cr = app.connections.valueAt(j);
2491            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2492                    && cr.binding.service.app != null
2493                    && cr.binding.service.app.lruSeq != mLruSeq
2494                    && !cr.binding.service.app.persistent) {
2495                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2496                        "service connection", cr, app);
2497            }
2498        }
2499        for (int j=app.conProviders.size()-1; j>=0; j--) {
2500            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2501            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2502                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2503                        "provider reference", cpr, app);
2504            }
2505        }
2506    }
2507
2508    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2509        if (uid == Process.SYSTEM_UID) {
2510            // The system gets to run in any process.  If there are multiple
2511            // processes with the same uid, just pick the first (this
2512            // should never happen).
2513            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2514            if (procs == null) return null;
2515            final int N = procs.size();
2516            for (int i = 0; i < N; i++) {
2517                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2518            }
2519        }
2520        ProcessRecord proc = mProcessNames.get(processName, uid);
2521        if (false && proc != null && !keepIfLarge
2522                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2523                && proc.lastCachedPss >= 4000) {
2524            // Turn this condition on to cause killing to happen regularly, for testing.
2525            if (proc.baseProcessTracker != null) {
2526                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2527            }
2528            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2529                    + "k from cached");
2530        } else if (proc != null && !keepIfLarge
2531                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2532                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2533            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2534            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2535                if (proc.baseProcessTracker != null) {
2536                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2537                }
2538                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2539                        + "k from cached");
2540            }
2541        }
2542        return proc;
2543    }
2544
2545    void ensurePackageDexOpt(String packageName) {
2546        IPackageManager pm = AppGlobals.getPackageManager();
2547        try {
2548            if (pm.performDexOpt(packageName)) {
2549                mDidDexOpt = true;
2550            }
2551        } catch (RemoteException e) {
2552        }
2553    }
2554
2555    boolean isNextTransitionForward() {
2556        int transit = mWindowManager.getPendingAppTransition();
2557        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2558                || transit == AppTransition.TRANSIT_TASK_OPEN
2559                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2560    }
2561
2562    final ProcessRecord startProcessLocked(String processName,
2563            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2564            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2565            boolean isolated, boolean keepIfLarge) {
2566        ProcessRecord app;
2567        if (!isolated) {
2568            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2569        } else {
2570            // If this is an isolated process, it can't re-use an existing process.
2571            app = null;
2572        }
2573        // We don't have to do anything more if:
2574        // (1) There is an existing application record; and
2575        // (2) The caller doesn't think it is dead, OR there is no thread
2576        //     object attached to it so we know it couldn't have crashed; and
2577        // (3) There is a pid assigned to it, so it is either starting or
2578        //     already running.
2579        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2580                + " app=" + app + " knownToBeDead=" + knownToBeDead
2581                + " thread=" + (app != null ? app.thread : null)
2582                + " pid=" + (app != null ? app.pid : -1));
2583        if (app != null && app.pid > 0) {
2584            if (!knownToBeDead || app.thread == null) {
2585                // We already have the app running, or are waiting for it to
2586                // come up (we have a pid but not yet its thread), so keep it.
2587                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2588                // If this is a new package in the process, add the package to the list
2589                app.addPackage(info.packageName, mProcessStats);
2590                return app;
2591            }
2592
2593            // An application record is attached to a previous process,
2594            // clean it up now.
2595            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2596            handleAppDiedLocked(app, true, true);
2597        }
2598
2599        String hostingNameStr = hostingName != null
2600                ? hostingName.flattenToShortString() : null;
2601
2602        if (!isolated) {
2603            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2604                // If we are in the background, then check to see if this process
2605                // is bad.  If so, we will just silently fail.
2606                if (mBadProcesses.get(info.processName, info.uid) != null) {
2607                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2608                            + "/" + info.processName);
2609                    return null;
2610                }
2611            } else {
2612                // When the user is explicitly starting a process, then clear its
2613                // crash count so that we won't make it bad until they see at
2614                // least one crash dialog again, and make the process good again
2615                // if it had been bad.
2616                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2617                        + "/" + info.processName);
2618                mProcessCrashTimes.remove(info.processName, info.uid);
2619                if (mBadProcesses.get(info.processName, info.uid) != null) {
2620                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2621                            UserHandle.getUserId(info.uid), info.uid,
2622                            info.processName);
2623                    mBadProcesses.remove(info.processName, info.uid);
2624                    if (app != null) {
2625                        app.bad = false;
2626                    }
2627                }
2628            }
2629        }
2630
2631        if (app == null) {
2632            app = newProcessRecordLocked(info, processName, isolated);
2633            if (app == null) {
2634                Slog.w(TAG, "Failed making new process record for "
2635                        + processName + "/" + info.uid + " isolated=" + isolated);
2636                return null;
2637            }
2638            mProcessNames.put(processName, app.uid, app);
2639            if (isolated) {
2640                mIsolatedProcesses.put(app.uid, app);
2641            }
2642        } else {
2643            // If this is a new package in the process, add the package to the list
2644            app.addPackage(info.packageName, mProcessStats);
2645        }
2646
2647        // If the system is not ready yet, then hold off on starting this
2648        // process until it is.
2649        if (!mProcessesReady
2650                && !isAllowedWhileBooting(info)
2651                && !allowWhileBooting) {
2652            if (!mProcessesOnHold.contains(app)) {
2653                mProcessesOnHold.add(app);
2654            }
2655            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2656            return app;
2657        }
2658
2659        startProcessLocked(app, hostingType, hostingNameStr);
2660        return (app.pid != 0) ? app : null;
2661    }
2662
2663    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2664        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2665    }
2666
2667    private final void startProcessLocked(ProcessRecord app,
2668            String hostingType, String hostingNameStr) {
2669        if (app.pid > 0 && app.pid != MY_PID) {
2670            synchronized (mPidsSelfLocked) {
2671                mPidsSelfLocked.remove(app.pid);
2672                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2673            }
2674            app.setPid(0);
2675        }
2676
2677        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2678                "startProcessLocked removing on hold: " + app);
2679        mProcessesOnHold.remove(app);
2680
2681        updateCpuStats();
2682
2683        try {
2684            int uid = app.uid;
2685
2686            int[] gids = null;
2687            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2688            if (!app.isolated) {
2689                int[] permGids = null;
2690                try {
2691                    final PackageManager pm = mContext.getPackageManager();
2692                    permGids = pm.getPackageGids(app.info.packageName);
2693
2694                    if (Environment.isExternalStorageEmulated()) {
2695                        if (pm.checkPermission(
2696                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2697                                app.info.packageName) == PERMISSION_GRANTED) {
2698                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2699                        } else {
2700                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2701                        }
2702                    }
2703                } catch (PackageManager.NameNotFoundException e) {
2704                    Slog.w(TAG, "Unable to retrieve gids", e);
2705                }
2706
2707                /*
2708                 * Add shared application GID so applications can share some
2709                 * resources like shared libraries
2710                 */
2711                if (permGids == null) {
2712                    gids = new int[1];
2713                } else {
2714                    gids = new int[permGids.length + 1];
2715                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2716                }
2717                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2718            }
2719            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2720                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2721                        && mTopComponent != null
2722                        && app.processName.equals(mTopComponent.getPackageName())) {
2723                    uid = 0;
2724                }
2725                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2726                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2727                    uid = 0;
2728                }
2729            }
2730            int debugFlags = 0;
2731            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2732                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2733                // Also turn on CheckJNI for debuggable apps. It's quite
2734                // awkward to turn on otherwise.
2735                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2736            }
2737            // Run the app in safe mode if its manifest requests so or the
2738            // system is booted in safe mode.
2739            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2740                Zygote.systemInSafeMode == true) {
2741                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2742            }
2743            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2744                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2745            }
2746            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2747                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2748            }
2749            if ("1".equals(SystemProperties.get("debug.assert"))) {
2750                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2751            }
2752
2753            // Start the process.  It will either succeed and return a result containing
2754            // the PID of the new process, or else throw a RuntimeException.
2755            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2756                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2757                    app.info.targetSdkVersion, app.info.seinfo, null);
2758
2759            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2760            synchronized (bs) {
2761                if (bs.isOnBattery()) {
2762                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2763                }
2764            }
2765
2766            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2767                    UserHandle.getUserId(uid), startResult.pid, uid,
2768                    app.processName, hostingType,
2769                    hostingNameStr != null ? hostingNameStr : "");
2770
2771            if (app.persistent) {
2772                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2773            }
2774
2775            StringBuilder buf = mStringBuilder;
2776            buf.setLength(0);
2777            buf.append("Start proc ");
2778            buf.append(app.processName);
2779            buf.append(" for ");
2780            buf.append(hostingType);
2781            if (hostingNameStr != null) {
2782                buf.append(" ");
2783                buf.append(hostingNameStr);
2784            }
2785            buf.append(": pid=");
2786            buf.append(startResult.pid);
2787            buf.append(" uid=");
2788            buf.append(uid);
2789            buf.append(" gids={");
2790            if (gids != null) {
2791                for (int gi=0; gi<gids.length; gi++) {
2792                    if (gi != 0) buf.append(", ");
2793                    buf.append(gids[gi]);
2794
2795                }
2796            }
2797            buf.append("}");
2798            Slog.i(TAG, buf.toString());
2799            app.setPid(startResult.pid);
2800            app.usingWrapper = startResult.usingWrapper;
2801            app.removed = false;
2802            synchronized (mPidsSelfLocked) {
2803                this.mPidsSelfLocked.put(startResult.pid, app);
2804                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2805                msg.obj = app;
2806                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2807                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2808            }
2809            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2810                    app.processName, app.info.uid);
2811            if (app.isolated) {
2812                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2813            }
2814        } catch (RuntimeException e) {
2815            // XXX do better error recovery.
2816            app.setPid(0);
2817            Slog.e(TAG, "Failure starting process " + app.processName, e);
2818        }
2819    }
2820
2821    void updateUsageStats(ActivityRecord component, boolean resumed) {
2822        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2823        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2824        if (resumed) {
2825            mUsageStatsService.noteResumeComponent(component.realActivity);
2826            synchronized (stats) {
2827                stats.noteActivityResumedLocked(component.app.uid);
2828            }
2829        } else {
2830            mUsageStatsService.notePauseComponent(component.realActivity);
2831            synchronized (stats) {
2832                stats.noteActivityPausedLocked(component.app.uid);
2833            }
2834        }
2835    }
2836
2837    Intent getHomeIntent() {
2838        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2839        intent.setComponent(mTopComponent);
2840        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2841            intent.addCategory(Intent.CATEGORY_HOME);
2842        }
2843        return intent;
2844    }
2845
2846    boolean startHomeActivityLocked(int userId) {
2847        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2848                && mTopAction == null) {
2849            // We are running in factory test mode, but unable to find
2850            // the factory test app, so just sit around displaying the
2851            // error message and don't try to start anything.
2852            return false;
2853        }
2854        Intent intent = getHomeIntent();
2855        ActivityInfo aInfo =
2856            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2857        if (aInfo != null) {
2858            intent.setComponent(new ComponentName(
2859                    aInfo.applicationInfo.packageName, aInfo.name));
2860            // Don't do this if the home app is currently being
2861            // instrumented.
2862            aInfo = new ActivityInfo(aInfo);
2863            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2864            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2865                    aInfo.applicationInfo.uid, true);
2866            if (app == null || app.instrumentationClass == null) {
2867                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2868                mStackSupervisor.startHomeActivity(intent, aInfo);
2869            }
2870        }
2871
2872        return true;
2873    }
2874
2875    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2876        ActivityInfo ai = null;
2877        ComponentName comp = intent.getComponent();
2878        try {
2879            if (comp != null) {
2880                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2881            } else {
2882                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2883                        intent,
2884                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2885                            flags, userId);
2886
2887                if (info != null) {
2888                    ai = info.activityInfo;
2889                }
2890            }
2891        } catch (RemoteException e) {
2892            // ignore
2893        }
2894
2895        return ai;
2896    }
2897
2898    /**
2899     * Starts the "new version setup screen" if appropriate.
2900     */
2901    void startSetupActivityLocked() {
2902        // Only do this once per boot.
2903        if (mCheckedForSetup) {
2904            return;
2905        }
2906
2907        // We will show this screen if the current one is a different
2908        // version than the last one shown, and we are not running in
2909        // low-level factory test mode.
2910        final ContentResolver resolver = mContext.getContentResolver();
2911        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2912                Settings.Global.getInt(resolver,
2913                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2914            mCheckedForSetup = true;
2915
2916            // See if we should be showing the platform update setup UI.
2917            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2918            List<ResolveInfo> ris = mContext.getPackageManager()
2919                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2920
2921            // We don't allow third party apps to replace this.
2922            ResolveInfo ri = null;
2923            for (int i=0; ris != null && i<ris.size(); i++) {
2924                if ((ris.get(i).activityInfo.applicationInfo.flags
2925                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2926                    ri = ris.get(i);
2927                    break;
2928                }
2929            }
2930
2931            if (ri != null) {
2932                String vers = ri.activityInfo.metaData != null
2933                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2934                        : null;
2935                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2936                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2937                            Intent.METADATA_SETUP_VERSION);
2938                }
2939                String lastVers = Settings.Secure.getString(
2940                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2941                if (vers != null && !vers.equals(lastVers)) {
2942                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2943                    intent.setComponent(new ComponentName(
2944                            ri.activityInfo.packageName, ri.activityInfo.name));
2945                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2946                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2947                }
2948            }
2949        }
2950    }
2951
2952    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2953        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2954    }
2955
2956    void enforceNotIsolatedCaller(String caller) {
2957        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2958            throw new SecurityException("Isolated process not allowed to call " + caller);
2959        }
2960    }
2961
2962    @Override
2963    public int getFrontActivityScreenCompatMode() {
2964        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2965        synchronized (this) {
2966            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2967        }
2968    }
2969
2970    @Override
2971    public void setFrontActivityScreenCompatMode(int mode) {
2972        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2973                "setFrontActivityScreenCompatMode");
2974        synchronized (this) {
2975            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2976        }
2977    }
2978
2979    @Override
2980    public int getPackageScreenCompatMode(String packageName) {
2981        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2982        synchronized (this) {
2983            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2984        }
2985    }
2986
2987    @Override
2988    public void setPackageScreenCompatMode(String packageName, int mode) {
2989        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2990                "setPackageScreenCompatMode");
2991        synchronized (this) {
2992            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2993        }
2994    }
2995
2996    @Override
2997    public boolean getPackageAskScreenCompat(String packageName) {
2998        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2999        synchronized (this) {
3000            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3001        }
3002    }
3003
3004    @Override
3005    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3006        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3007                "setPackageAskScreenCompat");
3008        synchronized (this) {
3009            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3010        }
3011    }
3012
3013    private void dispatchProcessesChanged() {
3014        int N;
3015        synchronized (this) {
3016            N = mPendingProcessChanges.size();
3017            if (mActiveProcessChanges.length < N) {
3018                mActiveProcessChanges = new ProcessChangeItem[N];
3019            }
3020            mPendingProcessChanges.toArray(mActiveProcessChanges);
3021            mAvailProcessChanges.addAll(mPendingProcessChanges);
3022            mPendingProcessChanges.clear();
3023            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3024        }
3025
3026        int i = mProcessObservers.beginBroadcast();
3027        while (i > 0) {
3028            i--;
3029            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3030            if (observer != null) {
3031                try {
3032                    for (int j=0; j<N; j++) {
3033                        ProcessChangeItem item = mActiveProcessChanges[j];
3034                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3035                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3036                                    + item.pid + " uid=" + item.uid + ": "
3037                                    + item.foregroundActivities);
3038                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3039                                    item.foregroundActivities);
3040                        }
3041                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3042                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3043                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3044                            observer.onImportanceChanged(item.pid, item.uid,
3045                                    item.importance);
3046                        }
3047                    }
3048                } catch (RemoteException e) {
3049                }
3050            }
3051        }
3052        mProcessObservers.finishBroadcast();
3053    }
3054
3055    private void dispatchProcessDied(int pid, int uid) {
3056        int i = mProcessObservers.beginBroadcast();
3057        while (i > 0) {
3058            i--;
3059            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3060            if (observer != null) {
3061                try {
3062                    observer.onProcessDied(pid, uid);
3063                } catch (RemoteException e) {
3064                }
3065            }
3066        }
3067        mProcessObservers.finishBroadcast();
3068    }
3069
3070    final void doPendingActivityLaunchesLocked(boolean doResume) {
3071        final int N = mPendingActivityLaunches.size();
3072        if (N <= 0) {
3073            return;
3074        }
3075        for (int i=0; i<N; i++) {
3076            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3077            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3078                    doResume && i == (N-1), null);
3079        }
3080        mPendingActivityLaunches.clear();
3081    }
3082
3083    @Override
3084    public final int startActivity(IApplicationThread caller, String callingPackage,
3085            Intent intent, String resolvedType, IBinder resultTo,
3086            String resultWho, int requestCode, int startFlags,
3087            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3088        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3089                resultWho, requestCode,
3090                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3091    }
3092
3093    @Override
3094    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3095            Intent intent, String resolvedType, IBinder resultTo,
3096            String resultWho, int requestCode, int startFlags,
3097            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3098        enforceNotIsolatedCaller("startActivity");
3099        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3100                false, true, "startActivity", null);
3101        // TODO: Switch to user app stacks here.
3102        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3103                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3104                null, null, options, userId, null);
3105    }
3106
3107    @Override
3108    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3109            Intent intent, String resolvedType, IBinder resultTo,
3110            String resultWho, int requestCode, int startFlags, String profileFile,
3111            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3112        enforceNotIsolatedCaller("startActivityAndWait");
3113        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3114                false, true, "startActivityAndWait", null);
3115        WaitResult res = new WaitResult();
3116        // TODO: Switch to user app stacks here.
3117        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3118                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3119                res, null, options, UserHandle.getCallingUserId(), null);
3120        return res;
3121    }
3122
3123    @Override
3124    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3125            Intent intent, String resolvedType, IBinder resultTo,
3126            String resultWho, int requestCode, int startFlags, Configuration config,
3127            Bundle options, int userId) {
3128        enforceNotIsolatedCaller("startActivityWithConfig");
3129        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3130                false, true, "startActivityWithConfig", null);
3131        // TODO: Switch to user app stacks here.
3132        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3133                resolvedType, resultTo, resultWho, requestCode, startFlags,
3134                null, null, null, config, options, userId, null);
3135        return ret;
3136    }
3137
3138    @Override
3139    public int startActivityIntentSender(IApplicationThread caller,
3140            IntentSender intent, Intent fillInIntent, String resolvedType,
3141            IBinder resultTo, String resultWho, int requestCode,
3142            int flagsMask, int flagsValues, Bundle options) {
3143        enforceNotIsolatedCaller("startActivityIntentSender");
3144        // Refuse possible leaked file descriptors
3145        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3146            throw new IllegalArgumentException("File descriptors passed in Intent");
3147        }
3148
3149        IIntentSender sender = intent.getTarget();
3150        if (!(sender instanceof PendingIntentRecord)) {
3151            throw new IllegalArgumentException("Bad PendingIntent object");
3152        }
3153
3154        PendingIntentRecord pir = (PendingIntentRecord)sender;
3155
3156        synchronized (this) {
3157            // If this is coming from the currently resumed activity, it is
3158            // effectively saying that app switches are allowed at this point.
3159            final ActivityStack stack = getFocusedStack();
3160            if (stack.mResumedActivity != null &&
3161                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3162                mAppSwitchesAllowedTime = 0;
3163            }
3164        }
3165        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3166                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3167        return ret;
3168    }
3169
3170    @Override
3171    public boolean startNextMatchingActivity(IBinder callingActivity,
3172            Intent intent, Bundle options) {
3173        // Refuse possible leaked file descriptors
3174        if (intent != null && intent.hasFileDescriptors() == true) {
3175            throw new IllegalArgumentException("File descriptors passed in Intent");
3176        }
3177
3178        synchronized (this) {
3179            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3180            if (r == null) {
3181                ActivityOptions.abort(options);
3182                return false;
3183            }
3184            if (r.app == null || r.app.thread == null) {
3185                // The caller is not running...  d'oh!
3186                ActivityOptions.abort(options);
3187                return false;
3188            }
3189            intent = new Intent(intent);
3190            // The caller is not allowed to change the data.
3191            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3192            // And we are resetting to find the next component...
3193            intent.setComponent(null);
3194
3195            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3196
3197            ActivityInfo aInfo = null;
3198            try {
3199                List<ResolveInfo> resolves =
3200                    AppGlobals.getPackageManager().queryIntentActivities(
3201                            intent, r.resolvedType,
3202                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3203                            UserHandle.getCallingUserId());
3204
3205                // Look for the original activity in the list...
3206                final int N = resolves != null ? resolves.size() : 0;
3207                for (int i=0; i<N; i++) {
3208                    ResolveInfo rInfo = resolves.get(i);
3209                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3210                            && rInfo.activityInfo.name.equals(r.info.name)) {
3211                        // We found the current one...  the next matching is
3212                        // after it.
3213                        i++;
3214                        if (i<N) {
3215                            aInfo = resolves.get(i).activityInfo;
3216                        }
3217                        if (debug) {
3218                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3219                                    + "/" + r.info.name);
3220                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3221                                    + "/" + aInfo.name);
3222                        }
3223                        break;
3224                    }
3225                }
3226            } catch (RemoteException e) {
3227            }
3228
3229            if (aInfo == null) {
3230                // Nobody who is next!
3231                ActivityOptions.abort(options);
3232                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3233                return false;
3234            }
3235
3236            intent.setComponent(new ComponentName(
3237                    aInfo.applicationInfo.packageName, aInfo.name));
3238            intent.setFlags(intent.getFlags()&~(
3239                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3240                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3241                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3242                    Intent.FLAG_ACTIVITY_NEW_TASK));
3243
3244            // Okay now we need to start the new activity, replacing the
3245            // currently running activity.  This is a little tricky because
3246            // we want to start the new one as if the current one is finished,
3247            // but not finish the current one first so that there is no flicker.
3248            // And thus...
3249            final boolean wasFinishing = r.finishing;
3250            r.finishing = true;
3251
3252            // Propagate reply information over to the new activity.
3253            final ActivityRecord resultTo = r.resultTo;
3254            final String resultWho = r.resultWho;
3255            final int requestCode = r.requestCode;
3256            r.resultTo = null;
3257            if (resultTo != null) {
3258                resultTo.removeResultsLocked(r, resultWho, requestCode);
3259            }
3260
3261            final long origId = Binder.clearCallingIdentity();
3262            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3263                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3264                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3265                    options, false, null, null);
3266            Binder.restoreCallingIdentity(origId);
3267
3268            r.finishing = wasFinishing;
3269            if (res != ActivityManager.START_SUCCESS) {
3270                return false;
3271            }
3272            return true;
3273        }
3274    }
3275
3276    final int startActivityInPackage(int uid, String callingPackage,
3277            Intent intent, String resolvedType, IBinder resultTo,
3278            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3279                    IActivityContainer container) {
3280
3281        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3282                false, true, "startActivityInPackage", null);
3283
3284        // TODO: Switch to user app stacks here.
3285        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3286                resultTo, resultWho, requestCode, startFlags,
3287                null, null, null, null, options, userId, container);
3288        return ret;
3289    }
3290
3291    @Override
3292    public final int startActivities(IApplicationThread caller, String callingPackage,
3293            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3294            int userId) {
3295        enforceNotIsolatedCaller("startActivities");
3296        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3297                false, true, "startActivity", null);
3298        // TODO: Switch to user app stacks here.
3299        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3300                resolvedTypes, resultTo, options, userId);
3301        return ret;
3302    }
3303
3304    final int startActivitiesInPackage(int uid, String callingPackage,
3305            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3306            Bundle options, int userId) {
3307
3308        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3309                false, true, "startActivityInPackage", null);
3310        // TODO: Switch to user app stacks here.
3311        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3312                resultTo, options, userId);
3313        return ret;
3314    }
3315
3316    final void addRecentTaskLocked(TaskRecord task) {
3317        int N = mRecentTasks.size();
3318        // Quick case: check if the top-most recent task is the same.
3319        if (N > 0 && mRecentTasks.get(0) == task) {
3320            return;
3321        }
3322        // Remove any existing entries that are the same kind of task.
3323        final Intent intent = task.intent;
3324        final boolean document = intent != null && intent.isDocument();
3325        for (int i=0; i<N; i++) {
3326            TaskRecord tr = mRecentTasks.get(i);
3327            if (task != tr) {
3328                if (task.userId != tr.userId) {
3329                    continue;
3330                }
3331                final Intent trIntent = tr.intent;
3332                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3333                    (intent == null || !intent.filterEquals(trIntent))) {
3334                    continue;
3335                }
3336                if (document || trIntent != null && trIntent.isDocument()) {
3337                    // Document tasks do not match other tasks.
3338                    continue;
3339                }
3340            }
3341
3342            // Either task and tr are the same or, their affinities match or their intents match
3343            // and neither of them is a document.
3344            tr.disposeThumbnail();
3345            mRecentTasks.remove(i);
3346            i--;
3347            N--;
3348            if (task.intent == null) {
3349                // If the new recent task we are adding is not fully
3350                // specified, then replace it with the existing recent task.
3351                task = tr;
3352            }
3353        }
3354        if (N >= MAX_RECENT_TASKS) {
3355            mRecentTasks.remove(N-1).disposeThumbnail();
3356        }
3357        mRecentTasks.add(0, task);
3358    }
3359
3360    @Override
3361    public void reportActivityFullyDrawn(IBinder token) {
3362        synchronized (this) {
3363            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3364            if (r == null) {
3365                return;
3366            }
3367            r.reportFullyDrawnLocked();
3368        }
3369    }
3370
3371    @Override
3372    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3373        synchronized (this) {
3374            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3375            if (r == null) {
3376                return;
3377            }
3378            final long origId = Binder.clearCallingIdentity();
3379            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3380            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3381                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3382            if (config != null) {
3383                r.frozenBeforeDestroy = true;
3384                if (!updateConfigurationLocked(config, r, false, false)) {
3385                    mStackSupervisor.resumeTopActivitiesLocked();
3386                }
3387            }
3388            Binder.restoreCallingIdentity(origId);
3389        }
3390    }
3391
3392    @Override
3393    public int getRequestedOrientation(IBinder token) {
3394        synchronized (this) {
3395            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3396            if (r == null) {
3397                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3398            }
3399            return mWindowManager.getAppOrientation(r.appToken);
3400        }
3401    }
3402
3403    /**
3404     * This is the internal entry point for handling Activity.finish().
3405     *
3406     * @param token The Binder token referencing the Activity we want to finish.
3407     * @param resultCode Result code, if any, from this Activity.
3408     * @param resultData Result data (Intent), if any, from this Activity.
3409     *
3410     * @return Returns true if the activity successfully finished, or false if it is still running.
3411     */
3412    @Override
3413    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3414        // Refuse possible leaked file descriptors
3415        if (resultData != null && resultData.hasFileDescriptors() == true) {
3416            throw new IllegalArgumentException("File descriptors passed in Intent");
3417        }
3418
3419        synchronized(this) {
3420            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3421            if (r == null) {
3422                return true;
3423            }
3424            if (mController != null) {
3425                // Find the first activity that is not finishing.
3426                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3427                if (next != null) {
3428                    // ask watcher if this is allowed
3429                    boolean resumeOK = true;
3430                    try {
3431                        resumeOK = mController.activityResuming(next.packageName);
3432                    } catch (RemoteException e) {
3433                        mController = null;
3434                        Watchdog.getInstance().setActivityController(null);
3435                    }
3436
3437                    if (!resumeOK) {
3438                        return false;
3439                    }
3440                }
3441            }
3442            final long origId = Binder.clearCallingIdentity();
3443            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3444                    resultData, "app-request", true);
3445            Binder.restoreCallingIdentity(origId);
3446            return res;
3447        }
3448    }
3449
3450    @Override
3451    public final void finishHeavyWeightApp() {
3452        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3453                != PackageManager.PERMISSION_GRANTED) {
3454            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3455                    + Binder.getCallingPid()
3456                    + ", uid=" + Binder.getCallingUid()
3457                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3458            Slog.w(TAG, msg);
3459            throw new SecurityException(msg);
3460        }
3461
3462        synchronized(this) {
3463            if (mHeavyWeightProcess == null) {
3464                return;
3465            }
3466
3467            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3468                    mHeavyWeightProcess.activities);
3469            for (int i=0; i<activities.size(); i++) {
3470                ActivityRecord r = activities.get(i);
3471                if (!r.finishing) {
3472                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3473                            null, "finish-heavy", true);
3474                }
3475            }
3476
3477            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3478                    mHeavyWeightProcess.userId, 0));
3479            mHeavyWeightProcess = null;
3480        }
3481    }
3482
3483    @Override
3484    public void crashApplication(int uid, int initialPid, String packageName,
3485            String message) {
3486        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3487                != PackageManager.PERMISSION_GRANTED) {
3488            String msg = "Permission Denial: crashApplication() from pid="
3489                    + Binder.getCallingPid()
3490                    + ", uid=" + Binder.getCallingUid()
3491                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3492            Slog.w(TAG, msg);
3493            throw new SecurityException(msg);
3494        }
3495
3496        synchronized(this) {
3497            ProcessRecord proc = null;
3498
3499            // Figure out which process to kill.  We don't trust that initialPid
3500            // still has any relation to current pids, so must scan through the
3501            // list.
3502            synchronized (mPidsSelfLocked) {
3503                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3504                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3505                    if (p.uid != uid) {
3506                        continue;
3507                    }
3508                    if (p.pid == initialPid) {
3509                        proc = p;
3510                        break;
3511                    }
3512                    if (p.pkgList.containsKey(packageName)) {
3513                        proc = p;
3514                    }
3515                }
3516            }
3517
3518            if (proc == null) {
3519                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3520                        + " initialPid=" + initialPid
3521                        + " packageName=" + packageName);
3522                return;
3523            }
3524
3525            if (proc.thread != null) {
3526                if (proc.pid == Process.myPid()) {
3527                    Log.w(TAG, "crashApplication: trying to crash self!");
3528                    return;
3529                }
3530                long ident = Binder.clearCallingIdentity();
3531                try {
3532                    proc.thread.scheduleCrash(message);
3533                } catch (RemoteException e) {
3534                }
3535                Binder.restoreCallingIdentity(ident);
3536            }
3537        }
3538    }
3539
3540    @Override
3541    public final void finishSubActivity(IBinder token, String resultWho,
3542            int requestCode) {
3543        synchronized(this) {
3544            final long origId = Binder.clearCallingIdentity();
3545            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3546            if (r != null) {
3547                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3548            }
3549            Binder.restoreCallingIdentity(origId);
3550        }
3551    }
3552
3553    @Override
3554    public boolean finishActivityAffinity(IBinder token) {
3555        synchronized(this) {
3556            final long origId = Binder.clearCallingIdentity();
3557            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3558            boolean res = false;
3559            if (r != null) {
3560                res = r.task.stack.finishActivityAffinityLocked(r);
3561            }
3562            Binder.restoreCallingIdentity(origId);
3563            return res;
3564        }
3565    }
3566
3567    @Override
3568    public boolean willActivityBeVisible(IBinder token) {
3569        synchronized(this) {
3570            ActivityStack stack = ActivityRecord.getStackLocked(token);
3571            if (stack != null) {
3572                return stack.willActivityBeVisibleLocked(token);
3573            }
3574            return false;
3575        }
3576    }
3577
3578    @Override
3579    public void overridePendingTransition(IBinder token, String packageName,
3580            int enterAnim, int exitAnim) {
3581        synchronized(this) {
3582            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3583            if (self == null) {
3584                return;
3585            }
3586
3587            final long origId = Binder.clearCallingIdentity();
3588
3589            if (self.state == ActivityState.RESUMED
3590                    || self.state == ActivityState.PAUSING) {
3591                mWindowManager.overridePendingAppTransition(packageName,
3592                        enterAnim, exitAnim, null);
3593            }
3594
3595            Binder.restoreCallingIdentity(origId);
3596        }
3597    }
3598
3599    /**
3600     * Main function for removing an existing process from the activity manager
3601     * as a result of that process going away.  Clears out all connections
3602     * to the process.
3603     */
3604    private final void handleAppDiedLocked(ProcessRecord app,
3605            boolean restarting, boolean allowRestart) {
3606        int pid = app.pid;
3607        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3608        if (!restarting) {
3609            removeLruProcessLocked(app);
3610            if (pid > 0) {
3611                ProcessList.remove(pid);
3612            }
3613        }
3614
3615        if (mProfileProc == app) {
3616            clearProfilerLocked();
3617        }
3618
3619        // Remove this application's activities from active lists.
3620        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3621
3622        app.activities.clear();
3623
3624        if (app.instrumentationClass != null) {
3625            Slog.w(TAG, "Crash of app " + app.processName
3626                  + " running instrumentation " + app.instrumentationClass);
3627            Bundle info = new Bundle();
3628            info.putString("shortMsg", "Process crashed.");
3629            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3630        }
3631
3632        if (!restarting) {
3633            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3634                // If there was nothing to resume, and we are not already
3635                // restarting this process, but there is a visible activity that
3636                // is hosted by the process...  then make sure all visible
3637                // activities are running, taking care of restarting this
3638                // process.
3639                if (hasVisibleActivities) {
3640                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3641                }
3642            }
3643        }
3644    }
3645
3646    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3647        IBinder threadBinder = thread.asBinder();
3648        // Find the application record.
3649        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3650            ProcessRecord rec = mLruProcesses.get(i);
3651            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3652                return i;
3653            }
3654        }
3655        return -1;
3656    }
3657
3658    final ProcessRecord getRecordForAppLocked(
3659            IApplicationThread thread) {
3660        if (thread == null) {
3661            return null;
3662        }
3663
3664        int appIndex = getLRURecordIndexForAppLocked(thread);
3665        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3666    }
3667
3668    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3669        // If there are no longer any background processes running,
3670        // and the app that died was not running instrumentation,
3671        // then tell everyone we are now low on memory.
3672        boolean haveBg = false;
3673        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3674            ProcessRecord rec = mLruProcesses.get(i);
3675            if (rec.thread != null
3676                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3677                haveBg = true;
3678                break;
3679            }
3680        }
3681
3682        if (!haveBg) {
3683            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3684            if (doReport) {
3685                long now = SystemClock.uptimeMillis();
3686                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3687                    doReport = false;
3688                } else {
3689                    mLastMemUsageReportTime = now;
3690                }
3691            }
3692            final ArrayList<ProcessMemInfo> memInfos
3693                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3694            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3695            long now = SystemClock.uptimeMillis();
3696            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3697                ProcessRecord rec = mLruProcesses.get(i);
3698                if (rec == dyingProc || rec.thread == null) {
3699                    continue;
3700                }
3701                if (doReport) {
3702                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3703                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3704                }
3705                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3706                    // The low memory report is overriding any current
3707                    // state for a GC request.  Make sure to do
3708                    // heavy/important/visible/foreground processes first.
3709                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3710                        rec.lastRequestedGc = 0;
3711                    } else {
3712                        rec.lastRequestedGc = rec.lastLowMemory;
3713                    }
3714                    rec.reportLowMemory = true;
3715                    rec.lastLowMemory = now;
3716                    mProcessesToGc.remove(rec);
3717                    addProcessToGcListLocked(rec);
3718                }
3719            }
3720            if (doReport) {
3721                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3722                mHandler.sendMessage(msg);
3723            }
3724            scheduleAppGcsLocked();
3725        }
3726    }
3727
3728    final void appDiedLocked(ProcessRecord app, int pid,
3729            IApplicationThread thread) {
3730
3731        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3732        synchronized (stats) {
3733            stats.noteProcessDiedLocked(app.info.uid, pid);
3734        }
3735
3736        // Clean up already done if the process has been re-started.
3737        if (app.pid == pid && app.thread != null &&
3738                app.thread.asBinder() == thread.asBinder()) {
3739            boolean doLowMem = app.instrumentationClass == null;
3740            boolean doOomAdj = doLowMem;
3741            if (!app.killedByAm) {
3742                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3743                        + ") has died.");
3744                mAllowLowerMemLevel = true;
3745            } else {
3746                // Note that we always want to do oom adj to update our state with the
3747                // new number of procs.
3748                mAllowLowerMemLevel = false;
3749                doLowMem = false;
3750            }
3751            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3752            if (DEBUG_CLEANUP) Slog.v(
3753                TAG, "Dying app: " + app + ", pid: " + pid
3754                + ", thread: " + thread.asBinder());
3755            handleAppDiedLocked(app, false, true);
3756
3757            if (doOomAdj) {
3758                updateOomAdjLocked();
3759            }
3760            if (doLowMem) {
3761                doLowMemReportIfNeededLocked(app);
3762            }
3763        } else if (app.pid != pid) {
3764            // A new process has already been started.
3765            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3766                    + ") has died and restarted (pid " + app.pid + ").");
3767            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3768        } else if (DEBUG_PROCESSES) {
3769            Slog.d(TAG, "Received spurious death notification for thread "
3770                    + thread.asBinder());
3771        }
3772    }
3773
3774    /**
3775     * If a stack trace dump file is configured, dump process stack traces.
3776     * @param clearTraces causes the dump file to be erased prior to the new
3777     *    traces being written, if true; when false, the new traces will be
3778     *    appended to any existing file content.
3779     * @param firstPids of dalvik VM processes to dump stack traces for first
3780     * @param lastPids of dalvik VM processes to dump stack traces for last
3781     * @param nativeProcs optional list of native process names to dump stack crawls
3782     * @return file containing stack traces, or null if no dump file is configured
3783     */
3784    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3785            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3786        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3787        if (tracesPath == null || tracesPath.length() == 0) {
3788            return null;
3789        }
3790
3791        File tracesFile = new File(tracesPath);
3792        try {
3793            File tracesDir = tracesFile.getParentFile();
3794            if (!tracesDir.exists()) {
3795                tracesFile.mkdirs();
3796                if (!SELinux.restorecon(tracesDir)) {
3797                    return null;
3798                }
3799            }
3800            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3801
3802            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3803            tracesFile.createNewFile();
3804            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3805        } catch (IOException e) {
3806            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3807            return null;
3808        }
3809
3810        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3811        return tracesFile;
3812    }
3813
3814    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3815            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3816        // Use a FileObserver to detect when traces finish writing.
3817        // The order of traces is considered important to maintain for legibility.
3818        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3819            @Override
3820            public synchronized void onEvent(int event, String path) { notify(); }
3821        };
3822
3823        try {
3824            observer.startWatching();
3825
3826            // First collect all of the stacks of the most important pids.
3827            if (firstPids != null) {
3828                try {
3829                    int num = firstPids.size();
3830                    for (int i = 0; i < num; i++) {
3831                        synchronized (observer) {
3832                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3833                            observer.wait(200);  // Wait for write-close, give up after 200msec
3834                        }
3835                    }
3836                } catch (InterruptedException e) {
3837                    Log.wtf(TAG, e);
3838                }
3839            }
3840
3841            // Next collect the stacks of the native pids
3842            if (nativeProcs != null) {
3843                int[] pids = Process.getPidsForCommands(nativeProcs);
3844                if (pids != null) {
3845                    for (int pid : pids) {
3846                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3847                    }
3848                }
3849            }
3850
3851            // Lastly, measure CPU usage.
3852            if (processCpuTracker != null) {
3853                processCpuTracker.init();
3854                System.gc();
3855                processCpuTracker.update();
3856                try {
3857                    synchronized (processCpuTracker) {
3858                        processCpuTracker.wait(500); // measure over 1/2 second.
3859                    }
3860                } catch (InterruptedException e) {
3861                }
3862                processCpuTracker.update();
3863
3864                // We'll take the stack crawls of just the top apps using CPU.
3865                final int N = processCpuTracker.countWorkingStats();
3866                int numProcs = 0;
3867                for (int i=0; i<N && numProcs<5; i++) {
3868                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3869                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3870                        numProcs++;
3871                        try {
3872                            synchronized (observer) {
3873                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3874                                observer.wait(200);  // Wait for write-close, give up after 200msec
3875                            }
3876                        } catch (InterruptedException e) {
3877                            Log.wtf(TAG, e);
3878                        }
3879
3880                    }
3881                }
3882            }
3883        } finally {
3884            observer.stopWatching();
3885        }
3886    }
3887
3888    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3889        if (true || IS_USER_BUILD) {
3890            return;
3891        }
3892        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3893        if (tracesPath == null || tracesPath.length() == 0) {
3894            return;
3895        }
3896
3897        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3898        StrictMode.allowThreadDiskWrites();
3899        try {
3900            final File tracesFile = new File(tracesPath);
3901            final File tracesDir = tracesFile.getParentFile();
3902            final File tracesTmp = new File(tracesDir, "__tmp__");
3903            try {
3904                if (!tracesDir.exists()) {
3905                    tracesFile.mkdirs();
3906                    if (!SELinux.restorecon(tracesDir.getPath())) {
3907                        return;
3908                    }
3909                }
3910                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3911
3912                if (tracesFile.exists()) {
3913                    tracesTmp.delete();
3914                    tracesFile.renameTo(tracesTmp);
3915                }
3916                StringBuilder sb = new StringBuilder();
3917                Time tobj = new Time();
3918                tobj.set(System.currentTimeMillis());
3919                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3920                sb.append(": ");
3921                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3922                sb.append(" since ");
3923                sb.append(msg);
3924                FileOutputStream fos = new FileOutputStream(tracesFile);
3925                fos.write(sb.toString().getBytes());
3926                if (app == null) {
3927                    fos.write("\n*** No application process!".getBytes());
3928                }
3929                fos.close();
3930                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3931            } catch (IOException e) {
3932                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3933                return;
3934            }
3935
3936            if (app != null) {
3937                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3938                firstPids.add(app.pid);
3939                dumpStackTraces(tracesPath, firstPids, null, null, null);
3940            }
3941
3942            File lastTracesFile = null;
3943            File curTracesFile = null;
3944            for (int i=9; i>=0; i--) {
3945                String name = String.format(Locale.US, "slow%02d.txt", i);
3946                curTracesFile = new File(tracesDir, name);
3947                if (curTracesFile.exists()) {
3948                    if (lastTracesFile != null) {
3949                        curTracesFile.renameTo(lastTracesFile);
3950                    } else {
3951                        curTracesFile.delete();
3952                    }
3953                }
3954                lastTracesFile = curTracesFile;
3955            }
3956            tracesFile.renameTo(curTracesFile);
3957            if (tracesTmp.exists()) {
3958                tracesTmp.renameTo(tracesFile);
3959            }
3960        } finally {
3961            StrictMode.setThreadPolicy(oldPolicy);
3962        }
3963    }
3964
3965    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3966            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3967        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3968        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3969
3970        if (mController != null) {
3971            try {
3972                // 0 == continue, -1 = kill process immediately
3973                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3974                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3975            } catch (RemoteException e) {
3976                mController = null;
3977                Watchdog.getInstance().setActivityController(null);
3978            }
3979        }
3980
3981        long anrTime = SystemClock.uptimeMillis();
3982        if (MONITOR_CPU_USAGE) {
3983            updateCpuStatsNow();
3984        }
3985
3986        synchronized (this) {
3987            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3988            if (mShuttingDown) {
3989                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3990                return;
3991            } else if (app.notResponding) {
3992                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3993                return;
3994            } else if (app.crashing) {
3995                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3996                return;
3997            }
3998
3999            // In case we come through here for the same app before completing
4000            // this one, mark as anring now so we will bail out.
4001            app.notResponding = true;
4002
4003            // Log the ANR to the event log.
4004            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4005                    app.processName, app.info.flags, annotation);
4006
4007            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4008            firstPids.add(app.pid);
4009
4010            int parentPid = app.pid;
4011            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4012            if (parentPid != app.pid) firstPids.add(parentPid);
4013
4014            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4015
4016            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4017                ProcessRecord r = mLruProcesses.get(i);
4018                if (r != null && r.thread != null) {
4019                    int pid = r.pid;
4020                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4021                        if (r.persistent) {
4022                            firstPids.add(pid);
4023                        } else {
4024                            lastPids.put(pid, Boolean.TRUE);
4025                        }
4026                    }
4027                }
4028            }
4029        }
4030
4031        // Log the ANR to the main log.
4032        StringBuilder info = new StringBuilder();
4033        info.setLength(0);
4034        info.append("ANR in ").append(app.processName);
4035        if (activity != null && activity.shortComponentName != null) {
4036            info.append(" (").append(activity.shortComponentName).append(")");
4037        }
4038        info.append("\n");
4039        info.append("PID: ").append(app.pid).append("\n");
4040        if (annotation != null) {
4041            info.append("Reason: ").append(annotation).append("\n");
4042        }
4043        if (parent != null && parent != activity) {
4044            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4045        }
4046
4047        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4048
4049        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4050                NATIVE_STACKS_OF_INTEREST);
4051
4052        String cpuInfo = null;
4053        if (MONITOR_CPU_USAGE) {
4054            updateCpuStatsNow();
4055            synchronized (mProcessCpuThread) {
4056                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4057            }
4058            info.append(processCpuTracker.printCurrentLoad());
4059            info.append(cpuInfo);
4060        }
4061
4062        info.append(processCpuTracker.printCurrentState(anrTime));
4063
4064        Slog.e(TAG, info.toString());
4065        if (tracesFile == null) {
4066            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4067            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4068        }
4069
4070        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4071                cpuInfo, tracesFile, null);
4072
4073        if (mController != null) {
4074            try {
4075                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4076                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4077                if (res != 0) {
4078                    if (res < 0 && app.pid != MY_PID) {
4079                        Process.killProcess(app.pid);
4080                    } else {
4081                        synchronized (this) {
4082                            mServices.scheduleServiceTimeoutLocked(app);
4083                        }
4084                    }
4085                    return;
4086                }
4087            } catch (RemoteException e) {
4088                mController = null;
4089                Watchdog.getInstance().setActivityController(null);
4090            }
4091        }
4092
4093        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4094        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4095                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4096
4097        synchronized (this) {
4098            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4099                killUnneededProcessLocked(app, "background ANR");
4100                return;
4101            }
4102
4103            // Set the app's notResponding state, and look up the errorReportReceiver
4104            makeAppNotRespondingLocked(app,
4105                    activity != null ? activity.shortComponentName : null,
4106                    annotation != null ? "ANR " + annotation : "ANR",
4107                    info.toString());
4108
4109            // Bring up the infamous App Not Responding dialog
4110            Message msg = Message.obtain();
4111            HashMap<String, Object> map = new HashMap<String, Object>();
4112            msg.what = SHOW_NOT_RESPONDING_MSG;
4113            msg.obj = map;
4114            msg.arg1 = aboveSystem ? 1 : 0;
4115            map.put("app", app);
4116            if (activity != null) {
4117                map.put("activity", activity);
4118            }
4119
4120            mHandler.sendMessage(msg);
4121        }
4122    }
4123
4124    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4125        if (!mLaunchWarningShown) {
4126            mLaunchWarningShown = true;
4127            mHandler.post(new Runnable() {
4128                @Override
4129                public void run() {
4130                    synchronized (ActivityManagerService.this) {
4131                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4132                        d.show();
4133                        mHandler.postDelayed(new Runnable() {
4134                            @Override
4135                            public void run() {
4136                                synchronized (ActivityManagerService.this) {
4137                                    d.dismiss();
4138                                    mLaunchWarningShown = false;
4139                                }
4140                            }
4141                        }, 4000);
4142                    }
4143                }
4144            });
4145        }
4146    }
4147
4148    @Override
4149    public boolean clearApplicationUserData(final String packageName,
4150            final IPackageDataObserver observer, int userId) {
4151        enforceNotIsolatedCaller("clearApplicationUserData");
4152        int uid = Binder.getCallingUid();
4153        int pid = Binder.getCallingPid();
4154        userId = handleIncomingUser(pid, uid,
4155                userId, false, true, "clearApplicationUserData", null);
4156        long callingId = Binder.clearCallingIdentity();
4157        try {
4158            IPackageManager pm = AppGlobals.getPackageManager();
4159            int pkgUid = -1;
4160            synchronized(this) {
4161                try {
4162                    pkgUid = pm.getPackageUid(packageName, userId);
4163                } catch (RemoteException e) {
4164                }
4165                if (pkgUid == -1) {
4166                    Slog.w(TAG, "Invalid packageName: " + packageName);
4167                    if (observer != null) {
4168                        try {
4169                            observer.onRemoveCompleted(packageName, false);
4170                        } catch (RemoteException e) {
4171                            Slog.i(TAG, "Observer no longer exists.");
4172                        }
4173                    }
4174                    return false;
4175                }
4176                if (uid == pkgUid || checkComponentPermission(
4177                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4178                        pid, uid, -1, true)
4179                        == PackageManager.PERMISSION_GRANTED) {
4180                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4181                } else {
4182                    throw new SecurityException("PID " + pid + " does not have permission "
4183                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4184                                    + " of package " + packageName);
4185                }
4186            }
4187
4188            try {
4189                // Clear application user data
4190                pm.clearApplicationUserData(packageName, observer, userId);
4191
4192                // Remove all permissions granted from/to this package
4193                removeUriPermissionsForPackageLocked(packageName, userId, true);
4194
4195                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4196                        Uri.fromParts("package", packageName, null));
4197                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4198                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4199                        null, null, 0, null, null, null, false, false, userId);
4200            } catch (RemoteException e) {
4201            }
4202        } finally {
4203            Binder.restoreCallingIdentity(callingId);
4204        }
4205        return true;
4206    }
4207
4208    @Override
4209    public void killBackgroundProcesses(final String packageName, int userId) {
4210        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4211                != PackageManager.PERMISSION_GRANTED &&
4212                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4213                        != PackageManager.PERMISSION_GRANTED) {
4214            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4215                    + Binder.getCallingPid()
4216                    + ", uid=" + Binder.getCallingUid()
4217                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4218            Slog.w(TAG, msg);
4219            throw new SecurityException(msg);
4220        }
4221
4222        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4223                userId, true, true, "killBackgroundProcesses", null);
4224        long callingId = Binder.clearCallingIdentity();
4225        try {
4226            IPackageManager pm = AppGlobals.getPackageManager();
4227            synchronized(this) {
4228                int appId = -1;
4229                try {
4230                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4231                } catch (RemoteException e) {
4232                }
4233                if (appId == -1) {
4234                    Slog.w(TAG, "Invalid packageName: " + packageName);
4235                    return;
4236                }
4237                killPackageProcessesLocked(packageName, appId, userId,
4238                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4239            }
4240        } finally {
4241            Binder.restoreCallingIdentity(callingId);
4242        }
4243    }
4244
4245    @Override
4246    public void killAllBackgroundProcesses() {
4247        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4248                != PackageManager.PERMISSION_GRANTED) {
4249            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4250                    + Binder.getCallingPid()
4251                    + ", uid=" + Binder.getCallingUid()
4252                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4253            Slog.w(TAG, msg);
4254            throw new SecurityException(msg);
4255        }
4256
4257        long callingId = Binder.clearCallingIdentity();
4258        try {
4259            synchronized(this) {
4260                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4261                final int NP = mProcessNames.getMap().size();
4262                for (int ip=0; ip<NP; ip++) {
4263                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4264                    final int NA = apps.size();
4265                    for (int ia=0; ia<NA; ia++) {
4266                        ProcessRecord app = apps.valueAt(ia);
4267                        if (app.persistent) {
4268                            // we don't kill persistent processes
4269                            continue;
4270                        }
4271                        if (app.removed) {
4272                            procs.add(app);
4273                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4274                            app.removed = true;
4275                            procs.add(app);
4276                        }
4277                    }
4278                }
4279
4280                int N = procs.size();
4281                for (int i=0; i<N; i++) {
4282                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4283                }
4284                mAllowLowerMemLevel = true;
4285                updateOomAdjLocked();
4286                doLowMemReportIfNeededLocked(null);
4287            }
4288        } finally {
4289            Binder.restoreCallingIdentity(callingId);
4290        }
4291    }
4292
4293    @Override
4294    public void forceStopPackage(final String packageName, int userId) {
4295        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4296                != PackageManager.PERMISSION_GRANTED) {
4297            String msg = "Permission Denial: forceStopPackage() from pid="
4298                    + Binder.getCallingPid()
4299                    + ", uid=" + Binder.getCallingUid()
4300                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4301            Slog.w(TAG, msg);
4302            throw new SecurityException(msg);
4303        }
4304        final int callingPid = Binder.getCallingPid();
4305        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4306                userId, true, true, "forceStopPackage", null);
4307        long callingId = Binder.clearCallingIdentity();
4308        try {
4309            IPackageManager pm = AppGlobals.getPackageManager();
4310            synchronized(this) {
4311                int[] users = userId == UserHandle.USER_ALL
4312                        ? getUsersLocked() : new int[] { userId };
4313                for (int user : users) {
4314                    int pkgUid = -1;
4315                    try {
4316                        pkgUid = pm.getPackageUid(packageName, user);
4317                    } catch (RemoteException e) {
4318                    }
4319                    if (pkgUid == -1) {
4320                        Slog.w(TAG, "Invalid packageName: " + packageName);
4321                        continue;
4322                    }
4323                    try {
4324                        pm.setPackageStoppedState(packageName, true, user);
4325                    } catch (RemoteException e) {
4326                    } catch (IllegalArgumentException e) {
4327                        Slog.w(TAG, "Failed trying to unstop package "
4328                                + packageName + ": " + e);
4329                    }
4330                    if (isUserRunningLocked(user, false)) {
4331                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4332                    }
4333                }
4334            }
4335        } finally {
4336            Binder.restoreCallingIdentity(callingId);
4337        }
4338    }
4339
4340    /*
4341     * The pkg name and app id have to be specified.
4342     */
4343    @Override
4344    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4345        if (pkg == null) {
4346            return;
4347        }
4348        // Make sure the uid is valid.
4349        if (appid < 0) {
4350            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4351            return;
4352        }
4353        int callerUid = Binder.getCallingUid();
4354        // Only the system server can kill an application
4355        if (callerUid == Process.SYSTEM_UID) {
4356            // Post an aysnc message to kill the application
4357            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4358            msg.arg1 = appid;
4359            msg.arg2 = 0;
4360            Bundle bundle = new Bundle();
4361            bundle.putString("pkg", pkg);
4362            bundle.putString("reason", reason);
4363            msg.obj = bundle;
4364            mHandler.sendMessage(msg);
4365        } else {
4366            throw new SecurityException(callerUid + " cannot kill pkg: " +
4367                    pkg);
4368        }
4369    }
4370
4371    @Override
4372    public void closeSystemDialogs(String reason) {
4373        enforceNotIsolatedCaller("closeSystemDialogs");
4374
4375        final int pid = Binder.getCallingPid();
4376        final int uid = Binder.getCallingUid();
4377        final long origId = Binder.clearCallingIdentity();
4378        try {
4379            synchronized (this) {
4380                // Only allow this from foreground processes, so that background
4381                // applications can't abuse it to prevent system UI from being shown.
4382                if (uid >= Process.FIRST_APPLICATION_UID) {
4383                    ProcessRecord proc;
4384                    synchronized (mPidsSelfLocked) {
4385                        proc = mPidsSelfLocked.get(pid);
4386                    }
4387                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4388                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4389                                + " from background process " + proc);
4390                        return;
4391                    }
4392                }
4393                closeSystemDialogsLocked(reason);
4394            }
4395        } finally {
4396            Binder.restoreCallingIdentity(origId);
4397        }
4398    }
4399
4400    void closeSystemDialogsLocked(String reason) {
4401        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4402        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4403                | Intent.FLAG_RECEIVER_FOREGROUND);
4404        if (reason != null) {
4405            intent.putExtra("reason", reason);
4406        }
4407        mWindowManager.closeSystemDialogs(reason);
4408
4409        mStackSupervisor.closeSystemDialogsLocked();
4410
4411        broadcastIntentLocked(null, null, intent, null,
4412                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4413                Process.SYSTEM_UID, UserHandle.USER_ALL);
4414    }
4415
4416    @Override
4417    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4418        enforceNotIsolatedCaller("getProcessMemoryInfo");
4419        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4420        for (int i=pids.length-1; i>=0; i--) {
4421            ProcessRecord proc;
4422            int oomAdj;
4423            synchronized (this) {
4424                synchronized (mPidsSelfLocked) {
4425                    proc = mPidsSelfLocked.get(pids[i]);
4426                    oomAdj = proc != null ? proc.setAdj : 0;
4427                }
4428            }
4429            infos[i] = new Debug.MemoryInfo();
4430            Debug.getMemoryInfo(pids[i], infos[i]);
4431            if (proc != null) {
4432                synchronized (this) {
4433                    if (proc.thread != null && proc.setAdj == oomAdj) {
4434                        // Record this for posterity if the process has been stable.
4435                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4436                                infos[i].getTotalUss(), false, proc.pkgList);
4437                    }
4438                }
4439            }
4440        }
4441        return infos;
4442    }
4443
4444    @Override
4445    public long[] getProcessPss(int[] pids) {
4446        enforceNotIsolatedCaller("getProcessPss");
4447        long[] pss = new long[pids.length];
4448        for (int i=pids.length-1; i>=0; i--) {
4449            ProcessRecord proc;
4450            int oomAdj;
4451            synchronized (this) {
4452                synchronized (mPidsSelfLocked) {
4453                    proc = mPidsSelfLocked.get(pids[i]);
4454                    oomAdj = proc != null ? proc.setAdj : 0;
4455                }
4456            }
4457            long[] tmpUss = new long[1];
4458            pss[i] = Debug.getPss(pids[i], tmpUss);
4459            if (proc != null) {
4460                synchronized (this) {
4461                    if (proc.thread != null && proc.setAdj == oomAdj) {
4462                        // Record this for posterity if the process has been stable.
4463                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4464                    }
4465                }
4466            }
4467        }
4468        return pss;
4469    }
4470
4471    @Override
4472    public void killApplicationProcess(String processName, int uid) {
4473        if (processName == null) {
4474            return;
4475        }
4476
4477        int callerUid = Binder.getCallingUid();
4478        // Only the system server can kill an application
4479        if (callerUid == Process.SYSTEM_UID) {
4480            synchronized (this) {
4481                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4482                if (app != null && app.thread != null) {
4483                    try {
4484                        app.thread.scheduleSuicide();
4485                    } catch (RemoteException e) {
4486                        // If the other end already died, then our work here is done.
4487                    }
4488                } else {
4489                    Slog.w(TAG, "Process/uid not found attempting kill of "
4490                            + processName + " / " + uid);
4491                }
4492            }
4493        } else {
4494            throw new SecurityException(callerUid + " cannot kill app process: " +
4495                    processName);
4496        }
4497    }
4498
4499    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4500        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4501                false, true, false, false, UserHandle.getUserId(uid), reason);
4502        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4503                Uri.fromParts("package", packageName, null));
4504        if (!mProcessesReady) {
4505            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4506                    | Intent.FLAG_RECEIVER_FOREGROUND);
4507        }
4508        intent.putExtra(Intent.EXTRA_UID, uid);
4509        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4510        broadcastIntentLocked(null, null, intent,
4511                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4512                false, false,
4513                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4514    }
4515
4516    private void forceStopUserLocked(int userId, String reason) {
4517        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4518        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4519        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4520                | Intent.FLAG_RECEIVER_FOREGROUND);
4521        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4522        broadcastIntentLocked(null, null, intent,
4523                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4524                false, false,
4525                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4526    }
4527
4528    private final boolean killPackageProcessesLocked(String packageName, int appId,
4529            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4530            boolean doit, boolean evenPersistent, String reason) {
4531        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4532
4533        // Remove all processes this package may have touched: all with the
4534        // same UID (except for the system or root user), and all whose name
4535        // matches the package name.
4536        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4537        final int NP = mProcessNames.getMap().size();
4538        for (int ip=0; ip<NP; ip++) {
4539            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4540            final int NA = apps.size();
4541            for (int ia=0; ia<NA; ia++) {
4542                ProcessRecord app = apps.valueAt(ia);
4543                if (app.persistent && !evenPersistent) {
4544                    // we don't kill persistent processes
4545                    continue;
4546                }
4547                if (app.removed) {
4548                    if (doit) {
4549                        procs.add(app);
4550                    }
4551                    continue;
4552                }
4553
4554                // Skip process if it doesn't meet our oom adj requirement.
4555                if (app.setAdj < minOomAdj) {
4556                    continue;
4557                }
4558
4559                // If no package is specified, we call all processes under the
4560                // give user id.
4561                if (packageName == null) {
4562                    if (app.userId != userId) {
4563                        continue;
4564                    }
4565                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4566                        continue;
4567                    }
4568                // Package has been specified, we want to hit all processes
4569                // that match it.  We need to qualify this by the processes
4570                // that are running under the specified app and user ID.
4571                } else {
4572                    if (UserHandle.getAppId(app.uid) != appId) {
4573                        continue;
4574                    }
4575                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4576                        continue;
4577                    }
4578                    if (!app.pkgList.containsKey(packageName)) {
4579                        continue;
4580                    }
4581                }
4582
4583                // Process has passed all conditions, kill it!
4584                if (!doit) {
4585                    return true;
4586                }
4587                app.removed = true;
4588                procs.add(app);
4589            }
4590        }
4591
4592        int N = procs.size();
4593        for (int i=0; i<N; i++) {
4594            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4595        }
4596        updateOomAdjLocked();
4597        return N > 0;
4598    }
4599
4600    private final boolean forceStopPackageLocked(String name, int appId,
4601            boolean callerWillRestart, boolean purgeCache, boolean doit,
4602            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4603        int i;
4604        int N;
4605
4606        if (userId == UserHandle.USER_ALL && name == null) {
4607            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4608        }
4609
4610        if (appId < 0 && name != null) {
4611            try {
4612                appId = UserHandle.getAppId(
4613                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4614            } catch (RemoteException e) {
4615            }
4616        }
4617
4618        if (doit) {
4619            if (name != null) {
4620                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4621                        + " user=" + userId + ": " + reason);
4622            } else {
4623                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4624            }
4625
4626            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4627            for (int ip=pmap.size()-1; ip>=0; ip--) {
4628                SparseArray<Long> ba = pmap.valueAt(ip);
4629                for (i=ba.size()-1; i>=0; i--) {
4630                    boolean remove = false;
4631                    final int entUid = ba.keyAt(i);
4632                    if (name != null) {
4633                        if (userId == UserHandle.USER_ALL) {
4634                            if (UserHandle.getAppId(entUid) == appId) {
4635                                remove = true;
4636                            }
4637                        } else {
4638                            if (entUid == UserHandle.getUid(userId, appId)) {
4639                                remove = true;
4640                            }
4641                        }
4642                    } else if (UserHandle.getUserId(entUid) == userId) {
4643                        remove = true;
4644                    }
4645                    if (remove) {
4646                        ba.removeAt(i);
4647                    }
4648                }
4649                if (ba.size() == 0) {
4650                    pmap.removeAt(ip);
4651                }
4652            }
4653        }
4654
4655        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4656                -100, callerWillRestart, true, doit, evenPersistent,
4657                name == null ? ("stop user " + userId) : ("stop " + name));
4658
4659        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4660            if (!doit) {
4661                return true;
4662            }
4663            didSomething = true;
4664        }
4665
4666        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4667            if (!doit) {
4668                return true;
4669            }
4670            didSomething = true;
4671        }
4672
4673        if (name == null) {
4674            // Remove all sticky broadcasts from this user.
4675            mStickyBroadcasts.remove(userId);
4676        }
4677
4678        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4679        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4680                userId, providers)) {
4681            if (!doit) {
4682                return true;
4683            }
4684            didSomething = true;
4685        }
4686        N = providers.size();
4687        for (i=0; i<N; i++) {
4688            removeDyingProviderLocked(null, providers.get(i), true);
4689        }
4690
4691        // Remove transient permissions granted from/to this package/user
4692        removeUriPermissionsForPackageLocked(name, userId, false);
4693
4694        if (name == null || uninstalling) {
4695            // Remove pending intents.  For now we only do this when force
4696            // stopping users, because we have some problems when doing this
4697            // for packages -- app widgets are not currently cleaned up for
4698            // such packages, so they can be left with bad pending intents.
4699            if (mIntentSenderRecords.size() > 0) {
4700                Iterator<WeakReference<PendingIntentRecord>> it
4701                        = mIntentSenderRecords.values().iterator();
4702                while (it.hasNext()) {
4703                    WeakReference<PendingIntentRecord> wpir = it.next();
4704                    if (wpir == null) {
4705                        it.remove();
4706                        continue;
4707                    }
4708                    PendingIntentRecord pir = wpir.get();
4709                    if (pir == null) {
4710                        it.remove();
4711                        continue;
4712                    }
4713                    if (name == null) {
4714                        // Stopping user, remove all objects for the user.
4715                        if (pir.key.userId != userId) {
4716                            // Not the same user, skip it.
4717                            continue;
4718                        }
4719                    } else {
4720                        if (UserHandle.getAppId(pir.uid) != appId) {
4721                            // Different app id, skip it.
4722                            continue;
4723                        }
4724                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4725                            // Different user, skip it.
4726                            continue;
4727                        }
4728                        if (!pir.key.packageName.equals(name)) {
4729                            // Different package, skip it.
4730                            continue;
4731                        }
4732                    }
4733                    if (!doit) {
4734                        return true;
4735                    }
4736                    didSomething = true;
4737                    it.remove();
4738                    pir.canceled = true;
4739                    if (pir.key.activity != null) {
4740                        pir.key.activity.pendingResults.remove(pir.ref);
4741                    }
4742                }
4743            }
4744        }
4745
4746        if (doit) {
4747            if (purgeCache && name != null) {
4748                AttributeCache ac = AttributeCache.instance();
4749                if (ac != null) {
4750                    ac.removePackage(name);
4751                }
4752            }
4753            if (mBooted) {
4754                mStackSupervisor.resumeTopActivitiesLocked();
4755                mStackSupervisor.scheduleIdleLocked();
4756            }
4757        }
4758
4759        return didSomething;
4760    }
4761
4762    private final boolean removeProcessLocked(ProcessRecord app,
4763            boolean callerWillRestart, boolean allowRestart, String reason) {
4764        final String name = app.processName;
4765        final int uid = app.uid;
4766        if (DEBUG_PROCESSES) Slog.d(
4767            TAG, "Force removing proc " + app.toShortString() + " (" + name
4768            + "/" + uid + ")");
4769
4770        mProcessNames.remove(name, uid);
4771        mIsolatedProcesses.remove(app.uid);
4772        if (mHeavyWeightProcess == app) {
4773            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4774                    mHeavyWeightProcess.userId, 0));
4775            mHeavyWeightProcess = null;
4776        }
4777        boolean needRestart = false;
4778        if (app.pid > 0 && app.pid != MY_PID) {
4779            int pid = app.pid;
4780            synchronized (mPidsSelfLocked) {
4781                mPidsSelfLocked.remove(pid);
4782                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4783            }
4784            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4785                    app.processName, app.info.uid);
4786            if (app.isolated) {
4787                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4788            }
4789            killUnneededProcessLocked(app, reason);
4790            handleAppDiedLocked(app, true, allowRestart);
4791            removeLruProcessLocked(app);
4792
4793            if (app.persistent && !app.isolated) {
4794                if (!callerWillRestart) {
4795                    addAppLocked(app.info, false);
4796                } else {
4797                    needRestart = true;
4798                }
4799            }
4800        } else {
4801            mRemovedProcesses.add(app);
4802        }
4803
4804        return needRestart;
4805    }
4806
4807    private final void processStartTimedOutLocked(ProcessRecord app) {
4808        final int pid = app.pid;
4809        boolean gone = false;
4810        synchronized (mPidsSelfLocked) {
4811            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4812            if (knownApp != null && knownApp.thread == null) {
4813                mPidsSelfLocked.remove(pid);
4814                gone = true;
4815            }
4816        }
4817
4818        if (gone) {
4819            Slog.w(TAG, "Process " + app + " failed to attach");
4820            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4821                    pid, app.uid, app.processName);
4822            mProcessNames.remove(app.processName, app.uid);
4823            mIsolatedProcesses.remove(app.uid);
4824            if (mHeavyWeightProcess == app) {
4825                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4826                        mHeavyWeightProcess.userId, 0));
4827                mHeavyWeightProcess = null;
4828            }
4829            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4830                    app.processName, app.info.uid);
4831            if (app.isolated) {
4832                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4833            }
4834            // Take care of any launching providers waiting for this process.
4835            checkAppInLaunchingProvidersLocked(app, true);
4836            // Take care of any services that are waiting for the process.
4837            mServices.processStartTimedOutLocked(app);
4838            killUnneededProcessLocked(app, "start timeout");
4839            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4840                Slog.w(TAG, "Unattached app died before backup, skipping");
4841                try {
4842                    IBackupManager bm = IBackupManager.Stub.asInterface(
4843                            ServiceManager.getService(Context.BACKUP_SERVICE));
4844                    bm.agentDisconnected(app.info.packageName);
4845                } catch (RemoteException e) {
4846                    // Can't happen; the backup manager is local
4847                }
4848            }
4849            if (isPendingBroadcastProcessLocked(pid)) {
4850                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4851                skipPendingBroadcastLocked(pid);
4852            }
4853        } else {
4854            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4855        }
4856    }
4857
4858    private final boolean attachApplicationLocked(IApplicationThread thread,
4859            int pid) {
4860
4861        // Find the application record that is being attached...  either via
4862        // the pid if we are running in multiple processes, or just pull the
4863        // next app record if we are emulating process with anonymous threads.
4864        ProcessRecord app;
4865        if (pid != MY_PID && pid >= 0) {
4866            synchronized (mPidsSelfLocked) {
4867                app = mPidsSelfLocked.get(pid);
4868            }
4869        } else {
4870            app = null;
4871        }
4872
4873        if (app == null) {
4874            Slog.w(TAG, "No pending application record for pid " + pid
4875                    + " (IApplicationThread " + thread + "); dropping process");
4876            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4877            if (pid > 0 && pid != MY_PID) {
4878                Process.killProcessQuiet(pid);
4879            } else {
4880                try {
4881                    thread.scheduleExit();
4882                } catch (Exception e) {
4883                    // Ignore exceptions.
4884                }
4885            }
4886            return false;
4887        }
4888
4889        // If this application record is still attached to a previous
4890        // process, clean it up now.
4891        if (app.thread != null) {
4892            handleAppDiedLocked(app, true, true);
4893        }
4894
4895        // Tell the process all about itself.
4896
4897        if (localLOGV) Slog.v(
4898                TAG, "Binding process pid " + pid + " to record " + app);
4899
4900        final String processName = app.processName;
4901        try {
4902            AppDeathRecipient adr = new AppDeathRecipient(
4903                    app, pid, thread);
4904            thread.asBinder().linkToDeath(adr, 0);
4905            app.deathRecipient = adr;
4906        } catch (RemoteException e) {
4907            app.resetPackageList(mProcessStats);
4908            startProcessLocked(app, "link fail", processName);
4909            return false;
4910        }
4911
4912        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4913
4914        app.makeActive(thread, mProcessStats);
4915        app.curAdj = app.setAdj = -100;
4916        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4917        app.forcingToForeground = null;
4918        updateProcessForegroundLocked(app, false, false);
4919        app.hasShownUi = false;
4920        app.debugging = false;
4921        app.cached = false;
4922
4923        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4924
4925        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4926        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4927
4928        if (!normalMode) {
4929            Slog.i(TAG, "Launching preboot mode app: " + app);
4930        }
4931
4932        if (localLOGV) Slog.v(
4933            TAG, "New app record " + app
4934            + " thread=" + thread.asBinder() + " pid=" + pid);
4935        try {
4936            int testMode = IApplicationThread.DEBUG_OFF;
4937            if (mDebugApp != null && mDebugApp.equals(processName)) {
4938                testMode = mWaitForDebugger
4939                    ? IApplicationThread.DEBUG_WAIT
4940                    : IApplicationThread.DEBUG_ON;
4941                app.debugging = true;
4942                if (mDebugTransient) {
4943                    mDebugApp = mOrigDebugApp;
4944                    mWaitForDebugger = mOrigWaitForDebugger;
4945                }
4946            }
4947            String profileFile = app.instrumentationProfileFile;
4948            ParcelFileDescriptor profileFd = null;
4949            boolean profileAutoStop = false;
4950            if (mProfileApp != null && mProfileApp.equals(processName)) {
4951                mProfileProc = app;
4952                profileFile = mProfileFile;
4953                profileFd = mProfileFd;
4954                profileAutoStop = mAutoStopProfiler;
4955            }
4956            boolean enableOpenGlTrace = false;
4957            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4958                enableOpenGlTrace = true;
4959                mOpenGlTraceApp = null;
4960            }
4961
4962            // If the app is being launched for restore or full backup, set it up specially
4963            boolean isRestrictedBackupMode = false;
4964            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4965                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4966                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4967                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4968            }
4969
4970            ensurePackageDexOpt(app.instrumentationInfo != null
4971                    ? app.instrumentationInfo.packageName
4972                    : app.info.packageName);
4973            if (app.instrumentationClass != null) {
4974                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4975            }
4976            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4977                    + processName + " with config " + mConfiguration);
4978            ApplicationInfo appInfo = app.instrumentationInfo != null
4979                    ? app.instrumentationInfo : app.info;
4980            app.compat = compatibilityInfoForPackageLocked(appInfo);
4981            if (profileFd != null) {
4982                profileFd = profileFd.dup();
4983            }
4984            thread.bindApplication(processName, appInfo, providers,
4985                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4986                    app.instrumentationArguments, app.instrumentationWatcher,
4987                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4988                    isRestrictedBackupMode || !normalMode, app.persistent,
4989                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4990                    mCoreSettingsObserver.getCoreSettingsLocked());
4991            updateLruProcessLocked(app, false, null);
4992            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4993        } catch (Exception e) {
4994            // todo: Yikes!  What should we do?  For now we will try to
4995            // start another process, but that could easily get us in
4996            // an infinite loop of restarting processes...
4997            Slog.w(TAG, "Exception thrown during bind!", e);
4998
4999            app.resetPackageList(mProcessStats);
5000            app.unlinkDeathRecipient();
5001            startProcessLocked(app, "bind fail", processName);
5002            return false;
5003        }
5004
5005        // Remove this record from the list of starting applications.
5006        mPersistentStartingProcesses.remove(app);
5007        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5008                "Attach application locked removing on hold: " + app);
5009        mProcessesOnHold.remove(app);
5010
5011        boolean badApp = false;
5012        boolean didSomething = false;
5013
5014        // See if the top visible activity is waiting to run in this process...
5015        if (normalMode) {
5016            try {
5017                if (mStackSupervisor.attachApplicationLocked(app)) {
5018                    didSomething = true;
5019                }
5020            } catch (Exception e) {
5021                badApp = true;
5022            }
5023        }
5024
5025        // Find any services that should be running in this process...
5026        if (!badApp) {
5027            try {
5028                didSomething |= mServices.attachApplicationLocked(app, processName);
5029            } catch (Exception e) {
5030                badApp = true;
5031            }
5032        }
5033
5034        // Check if a next-broadcast receiver is in this process...
5035        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5036            try {
5037                didSomething |= sendPendingBroadcastsLocked(app);
5038            } catch (Exception e) {
5039                // If the app died trying to launch the receiver we declare it 'bad'
5040                badApp = true;
5041            }
5042        }
5043
5044        // Check whether the next backup agent is in this process...
5045        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5046            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5047            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5048            try {
5049                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5050                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5051                        mBackupTarget.backupMode);
5052            } catch (Exception e) {
5053                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5054                e.printStackTrace();
5055            }
5056        }
5057
5058        if (badApp) {
5059            // todo: Also need to kill application to deal with all
5060            // kinds of exceptions.
5061            handleAppDiedLocked(app, false, true);
5062            return false;
5063        }
5064
5065        if (!didSomething) {
5066            updateOomAdjLocked();
5067        }
5068
5069        return true;
5070    }
5071
5072    @Override
5073    public final void attachApplication(IApplicationThread thread) {
5074        synchronized (this) {
5075            int callingPid = Binder.getCallingPid();
5076            final long origId = Binder.clearCallingIdentity();
5077            attachApplicationLocked(thread, callingPid);
5078            Binder.restoreCallingIdentity(origId);
5079        }
5080    }
5081
5082    @Override
5083    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5084        final long origId = Binder.clearCallingIdentity();
5085        synchronized (this) {
5086            ActivityStack stack = ActivityRecord.getStackLocked(token);
5087            if (stack != null) {
5088                ActivityRecord r =
5089                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5090                if (stopProfiling) {
5091                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5092                        try {
5093                            mProfileFd.close();
5094                        } catch (IOException e) {
5095                        }
5096                        clearProfilerLocked();
5097                    }
5098                }
5099            }
5100        }
5101        Binder.restoreCallingIdentity(origId);
5102    }
5103
5104    void enableScreenAfterBoot() {
5105        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5106                SystemClock.uptimeMillis());
5107        mWindowManager.enableScreenAfterBoot();
5108
5109        synchronized (this) {
5110            updateEventDispatchingLocked();
5111        }
5112    }
5113
5114    @Override
5115    public void showBootMessage(final CharSequence msg, final boolean always) {
5116        enforceNotIsolatedCaller("showBootMessage");
5117        mWindowManager.showBootMessage(msg, always);
5118    }
5119
5120    @Override
5121    public void dismissKeyguardOnNextActivity() {
5122        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5123        final long token = Binder.clearCallingIdentity();
5124        try {
5125            synchronized (this) {
5126                if (DEBUG_LOCKSCREEN) logLockScreen("");
5127                if (mLockScreenShown) {
5128                    mLockScreenShown = false;
5129                    comeOutOfSleepIfNeededLocked();
5130                }
5131                mStackSupervisor.setDismissKeyguard(true);
5132            }
5133        } finally {
5134            Binder.restoreCallingIdentity(token);
5135        }
5136    }
5137
5138    final void finishBooting() {
5139        IntentFilter pkgFilter = new IntentFilter();
5140        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5141        pkgFilter.addDataScheme("package");
5142        mContext.registerReceiver(new BroadcastReceiver() {
5143            @Override
5144            public void onReceive(Context context, Intent intent) {
5145                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5146                if (pkgs != null) {
5147                    for (String pkg : pkgs) {
5148                        synchronized (ActivityManagerService.this) {
5149                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5150                                    "finished booting")) {
5151                                setResultCode(Activity.RESULT_OK);
5152                                return;
5153                            }
5154                        }
5155                    }
5156                }
5157            }
5158        }, pkgFilter);
5159
5160        synchronized (this) {
5161            // Ensure that any processes we had put on hold are now started
5162            // up.
5163            final int NP = mProcessesOnHold.size();
5164            if (NP > 0) {
5165                ArrayList<ProcessRecord> procs =
5166                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5167                for (int ip=0; ip<NP; ip++) {
5168                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5169                            + procs.get(ip));
5170                    startProcessLocked(procs.get(ip), "on-hold", null);
5171                }
5172            }
5173
5174            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5175                // Start looking for apps that are abusing wake locks.
5176                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5177                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5178                // Tell anyone interested that we are done booting!
5179                SystemProperties.set("sys.boot_completed", "1");
5180                SystemProperties.set("dev.bootcomplete", "1");
5181                for (int i=0; i<mStartedUsers.size(); i++) {
5182                    UserStartedState uss = mStartedUsers.valueAt(i);
5183                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5184                        uss.mState = UserStartedState.STATE_RUNNING;
5185                        final int userId = mStartedUsers.keyAt(i);
5186                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5187                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5188                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5189                        broadcastIntentLocked(null, null, intent, null,
5190                                new IIntentReceiver.Stub() {
5191                                    @Override
5192                                    public void performReceive(Intent intent, int resultCode,
5193                                            String data, Bundle extras, boolean ordered,
5194                                            boolean sticky, int sendingUser) {
5195                                        synchronized (ActivityManagerService.this) {
5196                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5197                                                    true, false);
5198                                        }
5199                                    }
5200                                },
5201                                0, null, null,
5202                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5203                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5204                                userId);
5205                    }
5206                }
5207                scheduleStartRelatedUsersLocked();
5208            }
5209        }
5210    }
5211
5212    final void ensureBootCompleted() {
5213        boolean booting;
5214        boolean enableScreen;
5215        synchronized (this) {
5216            booting = mBooting;
5217            mBooting = false;
5218            enableScreen = !mBooted;
5219            mBooted = true;
5220        }
5221
5222        if (booting) {
5223            finishBooting();
5224        }
5225
5226        if (enableScreen) {
5227            enableScreenAfterBoot();
5228        }
5229    }
5230
5231    @Override
5232    public final void activityResumed(IBinder token) {
5233        final long origId = Binder.clearCallingIdentity();
5234        synchronized(this) {
5235            ActivityStack stack = ActivityRecord.getStackLocked(token);
5236            if (stack != null) {
5237                ActivityRecord.activityResumedLocked(token);
5238            }
5239        }
5240        Binder.restoreCallingIdentity(origId);
5241    }
5242
5243    @Override
5244    public final void activityPaused(IBinder token) {
5245        final long origId = Binder.clearCallingIdentity();
5246        synchronized(this) {
5247            ActivityStack stack = ActivityRecord.getStackLocked(token);
5248            if (stack != null) {
5249                stack.activityPausedLocked(token, false);
5250            }
5251        }
5252        Binder.restoreCallingIdentity(origId);
5253    }
5254
5255    @Override
5256    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5257            CharSequence description) {
5258        if (localLOGV) Slog.v(
5259            TAG, "Activity stopped: token=" + token);
5260
5261        // Refuse possible leaked file descriptors
5262        if (icicle != null && icicle.hasFileDescriptors()) {
5263            throw new IllegalArgumentException("File descriptors passed in Bundle");
5264        }
5265
5266        ActivityRecord r = null;
5267
5268        final long origId = Binder.clearCallingIdentity();
5269
5270        synchronized (this) {
5271            r = ActivityRecord.isInStackLocked(token);
5272            if (r != null) {
5273                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5274            }
5275        }
5276
5277        if (r != null) {
5278            sendPendingThumbnail(r, null, null, null, false);
5279        }
5280
5281        trimApplications();
5282
5283        Binder.restoreCallingIdentity(origId);
5284    }
5285
5286    @Override
5287    public final void activityDestroyed(IBinder token) {
5288        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5289        synchronized (this) {
5290            ActivityStack stack = ActivityRecord.getStackLocked(token);
5291            if (stack != null) {
5292                stack.activityDestroyedLocked(token);
5293            }
5294        }
5295    }
5296
5297    @Override
5298    public String getCallingPackage(IBinder token) {
5299        synchronized (this) {
5300            ActivityRecord r = getCallingRecordLocked(token);
5301            return r != null ? r.info.packageName : null;
5302        }
5303    }
5304
5305    @Override
5306    public ComponentName getCallingActivity(IBinder token) {
5307        synchronized (this) {
5308            ActivityRecord r = getCallingRecordLocked(token);
5309            return r != null ? r.intent.getComponent() : null;
5310        }
5311    }
5312
5313    private ActivityRecord getCallingRecordLocked(IBinder token) {
5314        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5315        if (r == null) {
5316            return null;
5317        }
5318        return r.resultTo;
5319    }
5320
5321    @Override
5322    public ComponentName getActivityClassForToken(IBinder token) {
5323        synchronized(this) {
5324            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5325            if (r == null) {
5326                return null;
5327            }
5328            return r.intent.getComponent();
5329        }
5330    }
5331
5332    @Override
5333    public String getPackageForToken(IBinder token) {
5334        synchronized(this) {
5335            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5336            if (r == null) {
5337                return null;
5338            }
5339            return r.packageName;
5340        }
5341    }
5342
5343    @Override
5344    public IIntentSender getIntentSender(int type,
5345            String packageName, IBinder token, String resultWho,
5346            int requestCode, Intent[] intents, String[] resolvedTypes,
5347            int flags, Bundle options, int userId) {
5348        enforceNotIsolatedCaller("getIntentSender");
5349        // Refuse possible leaked file descriptors
5350        if (intents != null) {
5351            if (intents.length < 1) {
5352                throw new IllegalArgumentException("Intents array length must be >= 1");
5353            }
5354            for (int i=0; i<intents.length; i++) {
5355                Intent intent = intents[i];
5356                if (intent != null) {
5357                    if (intent.hasFileDescriptors()) {
5358                        throw new IllegalArgumentException("File descriptors passed in Intent");
5359                    }
5360                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5361                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5362                        throw new IllegalArgumentException(
5363                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5364                    }
5365                    intents[i] = new Intent(intent);
5366                }
5367            }
5368            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5369                throw new IllegalArgumentException(
5370                        "Intent array length does not match resolvedTypes length");
5371            }
5372        }
5373        if (options != null) {
5374            if (options.hasFileDescriptors()) {
5375                throw new IllegalArgumentException("File descriptors passed in options");
5376            }
5377        }
5378
5379        synchronized(this) {
5380            int callingUid = Binder.getCallingUid();
5381            int origUserId = userId;
5382            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5383                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5384                    "getIntentSender", null);
5385            if (origUserId == UserHandle.USER_CURRENT) {
5386                // We don't want to evaluate this until the pending intent is
5387                // actually executed.  However, we do want to always do the
5388                // security checking for it above.
5389                userId = UserHandle.USER_CURRENT;
5390            }
5391            try {
5392                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5393                    int uid = AppGlobals.getPackageManager()
5394                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5395                    if (!UserHandle.isSameApp(callingUid, uid)) {
5396                        String msg = "Permission Denial: getIntentSender() from pid="
5397                            + Binder.getCallingPid()
5398                            + ", uid=" + Binder.getCallingUid()
5399                            + ", (need uid=" + uid + ")"
5400                            + " is not allowed to send as package " + packageName;
5401                        Slog.w(TAG, msg);
5402                        throw new SecurityException(msg);
5403                    }
5404                }
5405
5406                return getIntentSenderLocked(type, packageName, callingUid, userId,
5407                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5408
5409            } catch (RemoteException e) {
5410                throw new SecurityException(e);
5411            }
5412        }
5413    }
5414
5415    IIntentSender getIntentSenderLocked(int type, String packageName,
5416            int callingUid, int userId, IBinder token, String resultWho,
5417            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5418            Bundle options) {
5419        if (DEBUG_MU)
5420            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5421        ActivityRecord activity = null;
5422        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5423            activity = ActivityRecord.isInStackLocked(token);
5424            if (activity == null) {
5425                return null;
5426            }
5427            if (activity.finishing) {
5428                return null;
5429            }
5430        }
5431
5432        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5433        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5434        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5435        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5436                |PendingIntent.FLAG_UPDATE_CURRENT);
5437
5438        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5439                type, packageName, activity, resultWho,
5440                requestCode, intents, resolvedTypes, flags, options, userId);
5441        WeakReference<PendingIntentRecord> ref;
5442        ref = mIntentSenderRecords.get(key);
5443        PendingIntentRecord rec = ref != null ? ref.get() : null;
5444        if (rec != null) {
5445            if (!cancelCurrent) {
5446                if (updateCurrent) {
5447                    if (rec.key.requestIntent != null) {
5448                        rec.key.requestIntent.replaceExtras(intents != null ?
5449                                intents[intents.length - 1] : null);
5450                    }
5451                    if (intents != null) {
5452                        intents[intents.length-1] = rec.key.requestIntent;
5453                        rec.key.allIntents = intents;
5454                        rec.key.allResolvedTypes = resolvedTypes;
5455                    } else {
5456                        rec.key.allIntents = null;
5457                        rec.key.allResolvedTypes = null;
5458                    }
5459                }
5460                return rec;
5461            }
5462            rec.canceled = true;
5463            mIntentSenderRecords.remove(key);
5464        }
5465        if (noCreate) {
5466            return rec;
5467        }
5468        rec = new PendingIntentRecord(this, key, callingUid);
5469        mIntentSenderRecords.put(key, rec.ref);
5470        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5471            if (activity.pendingResults == null) {
5472                activity.pendingResults
5473                        = new HashSet<WeakReference<PendingIntentRecord>>();
5474            }
5475            activity.pendingResults.add(rec.ref);
5476        }
5477        return rec;
5478    }
5479
5480    @Override
5481    public void cancelIntentSender(IIntentSender sender) {
5482        if (!(sender instanceof PendingIntentRecord)) {
5483            return;
5484        }
5485        synchronized(this) {
5486            PendingIntentRecord rec = (PendingIntentRecord)sender;
5487            try {
5488                int uid = AppGlobals.getPackageManager()
5489                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5490                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5491                    String msg = "Permission Denial: cancelIntentSender() from pid="
5492                        + Binder.getCallingPid()
5493                        + ", uid=" + Binder.getCallingUid()
5494                        + " is not allowed to cancel packges "
5495                        + rec.key.packageName;
5496                    Slog.w(TAG, msg);
5497                    throw new SecurityException(msg);
5498                }
5499            } catch (RemoteException e) {
5500                throw new SecurityException(e);
5501            }
5502            cancelIntentSenderLocked(rec, true);
5503        }
5504    }
5505
5506    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5507        rec.canceled = true;
5508        mIntentSenderRecords.remove(rec.key);
5509        if (cleanActivity && rec.key.activity != null) {
5510            rec.key.activity.pendingResults.remove(rec.ref);
5511        }
5512    }
5513
5514    @Override
5515    public String getPackageForIntentSender(IIntentSender pendingResult) {
5516        if (!(pendingResult instanceof PendingIntentRecord)) {
5517            return null;
5518        }
5519        try {
5520            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5521            return res.key.packageName;
5522        } catch (ClassCastException e) {
5523        }
5524        return null;
5525    }
5526
5527    @Override
5528    public int getUidForIntentSender(IIntentSender sender) {
5529        if (sender instanceof PendingIntentRecord) {
5530            try {
5531                PendingIntentRecord res = (PendingIntentRecord)sender;
5532                return res.uid;
5533            } catch (ClassCastException e) {
5534            }
5535        }
5536        return -1;
5537    }
5538
5539    @Override
5540    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5541        if (!(pendingResult instanceof PendingIntentRecord)) {
5542            return false;
5543        }
5544        try {
5545            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5546            if (res.key.allIntents == null) {
5547                return false;
5548            }
5549            for (int i=0; i<res.key.allIntents.length; i++) {
5550                Intent intent = res.key.allIntents[i];
5551                if (intent.getPackage() != null && intent.getComponent() != null) {
5552                    return false;
5553                }
5554            }
5555            return true;
5556        } catch (ClassCastException e) {
5557        }
5558        return false;
5559    }
5560
5561    @Override
5562    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5563        if (!(pendingResult instanceof PendingIntentRecord)) {
5564            return false;
5565        }
5566        try {
5567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5568            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5569                return true;
5570            }
5571            return false;
5572        } catch (ClassCastException e) {
5573        }
5574        return false;
5575    }
5576
5577    @Override
5578    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5579        if (!(pendingResult instanceof PendingIntentRecord)) {
5580            return null;
5581        }
5582        try {
5583            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5584            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5585        } catch (ClassCastException e) {
5586        }
5587        return null;
5588    }
5589
5590    @Override
5591    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5592        if (!(pendingResult instanceof PendingIntentRecord)) {
5593            return null;
5594        }
5595        try {
5596            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5597            Intent intent = res.key.requestIntent;
5598            if (intent != null) {
5599                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5600                        || res.lastTagPrefix.equals(prefix))) {
5601                    return res.lastTag;
5602                }
5603                res.lastTagPrefix = prefix;
5604                StringBuilder sb = new StringBuilder(128);
5605                if (prefix != null) {
5606                    sb.append(prefix);
5607                }
5608                if (intent.getAction() != null) {
5609                    sb.append(intent.getAction());
5610                } else if (intent.getComponent() != null) {
5611                    intent.getComponent().appendShortString(sb);
5612                } else {
5613                    sb.append("?");
5614                }
5615                return res.lastTag = sb.toString();
5616            }
5617        } catch (ClassCastException e) {
5618        }
5619        return null;
5620    }
5621
5622    @Override
5623    public void setProcessLimit(int max) {
5624        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5625                "setProcessLimit()");
5626        synchronized (this) {
5627            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5628            mProcessLimitOverride = max;
5629        }
5630        trimApplications();
5631    }
5632
5633    @Override
5634    public int getProcessLimit() {
5635        synchronized (this) {
5636            return mProcessLimitOverride;
5637        }
5638    }
5639
5640    void foregroundTokenDied(ForegroundToken token) {
5641        synchronized (ActivityManagerService.this) {
5642            synchronized (mPidsSelfLocked) {
5643                ForegroundToken cur
5644                    = mForegroundProcesses.get(token.pid);
5645                if (cur != token) {
5646                    return;
5647                }
5648                mForegroundProcesses.remove(token.pid);
5649                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5650                if (pr == null) {
5651                    return;
5652                }
5653                pr.forcingToForeground = null;
5654                updateProcessForegroundLocked(pr, false, false);
5655            }
5656            updateOomAdjLocked();
5657        }
5658    }
5659
5660    @Override
5661    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5662        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5663                "setProcessForeground()");
5664        synchronized(this) {
5665            boolean changed = false;
5666
5667            synchronized (mPidsSelfLocked) {
5668                ProcessRecord pr = mPidsSelfLocked.get(pid);
5669                if (pr == null && isForeground) {
5670                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5671                    return;
5672                }
5673                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5674                if (oldToken != null) {
5675                    oldToken.token.unlinkToDeath(oldToken, 0);
5676                    mForegroundProcesses.remove(pid);
5677                    if (pr != null) {
5678                        pr.forcingToForeground = null;
5679                    }
5680                    changed = true;
5681                }
5682                if (isForeground && token != null) {
5683                    ForegroundToken newToken = new ForegroundToken() {
5684                        @Override
5685                        public void binderDied() {
5686                            foregroundTokenDied(this);
5687                        }
5688                    };
5689                    newToken.pid = pid;
5690                    newToken.token = token;
5691                    try {
5692                        token.linkToDeath(newToken, 0);
5693                        mForegroundProcesses.put(pid, newToken);
5694                        pr.forcingToForeground = token;
5695                        changed = true;
5696                    } catch (RemoteException e) {
5697                        // If the process died while doing this, we will later
5698                        // do the cleanup with the process death link.
5699                    }
5700                }
5701            }
5702
5703            if (changed) {
5704                updateOomAdjLocked();
5705            }
5706        }
5707    }
5708
5709    // =========================================================
5710    // PERMISSIONS
5711    // =========================================================
5712
5713    static class PermissionController extends IPermissionController.Stub {
5714        ActivityManagerService mActivityManagerService;
5715        PermissionController(ActivityManagerService activityManagerService) {
5716            mActivityManagerService = activityManagerService;
5717        }
5718
5719        @Override
5720        public boolean checkPermission(String permission, int pid, int uid) {
5721            return mActivityManagerService.checkPermission(permission, pid,
5722                    uid) == PackageManager.PERMISSION_GRANTED;
5723        }
5724    }
5725
5726    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5727        @Override
5728        public int checkComponentPermission(String permission, int pid, int uid,
5729                int owningUid, boolean exported) {
5730            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5731                    owningUid, exported);
5732        }
5733
5734        @Override
5735        public Object getAMSLock() {
5736            return ActivityManagerService.this;
5737        }
5738    }
5739
5740    /**
5741     * This can be called with or without the global lock held.
5742     */
5743    int checkComponentPermission(String permission, int pid, int uid,
5744            int owningUid, boolean exported) {
5745        // We might be performing an operation on behalf of an indirect binder
5746        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5747        // client identity accordingly before proceeding.
5748        Identity tlsIdentity = sCallerIdentity.get();
5749        if (tlsIdentity != null) {
5750            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5751                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5752            uid = tlsIdentity.uid;
5753            pid = tlsIdentity.pid;
5754        }
5755
5756        if (pid == MY_PID) {
5757            return PackageManager.PERMISSION_GRANTED;
5758        }
5759
5760        return ActivityManager.checkComponentPermission(permission, uid,
5761                owningUid, exported);
5762    }
5763
5764    /**
5765     * As the only public entry point for permissions checking, this method
5766     * can enforce the semantic that requesting a check on a null global
5767     * permission is automatically denied.  (Internally a null permission
5768     * string is used when calling {@link #checkComponentPermission} in cases
5769     * when only uid-based security is needed.)
5770     *
5771     * This can be called with or without the global lock held.
5772     */
5773    @Override
5774    public int checkPermission(String permission, int pid, int uid) {
5775        if (permission == null) {
5776            return PackageManager.PERMISSION_DENIED;
5777        }
5778        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5779    }
5780
5781    /**
5782     * Binder IPC calls go through the public entry point.
5783     * This can be called with or without the global lock held.
5784     */
5785    int checkCallingPermission(String permission) {
5786        return checkPermission(permission,
5787                Binder.getCallingPid(),
5788                UserHandle.getAppId(Binder.getCallingUid()));
5789    }
5790
5791    /**
5792     * This can be called with or without the global lock held.
5793     */
5794    void enforceCallingPermission(String permission, String func) {
5795        if (checkCallingPermission(permission)
5796                == PackageManager.PERMISSION_GRANTED) {
5797            return;
5798        }
5799
5800        String msg = "Permission Denial: " + func + " from pid="
5801                + Binder.getCallingPid()
5802                + ", uid=" + Binder.getCallingUid()
5803                + " requires " + permission;
5804        Slog.w(TAG, msg);
5805        throw new SecurityException(msg);
5806    }
5807
5808    /**
5809     * Determine if UID is holding permissions required to access {@link Uri} in
5810     * the given {@link ProviderInfo}. Final permission checking is always done
5811     * in {@link ContentProvider}.
5812     */
5813    private final boolean checkHoldingPermissionsLocked(
5814            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5815        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5816                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5817
5818        if (pi.applicationInfo.uid == uid) {
5819            return true;
5820        } else if (!pi.exported) {
5821            return false;
5822        }
5823
5824        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5825        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5826        try {
5827            // check if target holds top-level <provider> permissions
5828            if (!readMet && pi.readPermission != null
5829                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5830                readMet = true;
5831            }
5832            if (!writeMet && pi.writePermission != null
5833                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5834                writeMet = true;
5835            }
5836
5837            // track if unprotected read/write is allowed; any denied
5838            // <path-permission> below removes this ability
5839            boolean allowDefaultRead = pi.readPermission == null;
5840            boolean allowDefaultWrite = pi.writePermission == null;
5841
5842            // check if target holds any <path-permission> that match uri
5843            final PathPermission[] pps = pi.pathPermissions;
5844            if (pps != null) {
5845                final String path = uri.getPath();
5846                int i = pps.length;
5847                while (i > 0 && (!readMet || !writeMet)) {
5848                    i--;
5849                    PathPermission pp = pps[i];
5850                    if (pp.match(path)) {
5851                        if (!readMet) {
5852                            final String pprperm = pp.getReadPermission();
5853                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5854                                    + pprperm + " for " + pp.getPath()
5855                                    + ": match=" + pp.match(path)
5856                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5857                            if (pprperm != null) {
5858                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5859                                    readMet = true;
5860                                } else {
5861                                    allowDefaultRead = false;
5862                                }
5863                            }
5864                        }
5865                        if (!writeMet) {
5866                            final String ppwperm = pp.getWritePermission();
5867                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5868                                    + ppwperm + " for " + pp.getPath()
5869                                    + ": match=" + pp.match(path)
5870                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5871                            if (ppwperm != null) {
5872                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5873                                    writeMet = true;
5874                                } else {
5875                                    allowDefaultWrite = false;
5876                                }
5877                            }
5878                        }
5879                    }
5880                }
5881            }
5882
5883            // grant unprotected <provider> read/write, if not blocked by
5884            // <path-permission> above
5885            if (allowDefaultRead) readMet = true;
5886            if (allowDefaultWrite) writeMet = true;
5887
5888        } catch (RemoteException e) {
5889            return false;
5890        }
5891
5892        return readMet && writeMet;
5893    }
5894
5895    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5896        ProviderInfo pi = null;
5897        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5898        if (cpr != null) {
5899            pi = cpr.info;
5900        } else {
5901            try {
5902                pi = AppGlobals.getPackageManager().resolveContentProvider(
5903                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5904            } catch (RemoteException ex) {
5905            }
5906        }
5907        return pi;
5908    }
5909
5910    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5911        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5912        if (targetUris != null) {
5913            return targetUris.get(uri);
5914        } else {
5915            return null;
5916        }
5917    }
5918
5919    private UriPermission findOrCreateUriPermissionLocked(
5920            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5921        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5922        if (targetUris == null) {
5923            targetUris = Maps.newArrayMap();
5924            mGrantedUriPermissions.put(targetUid, targetUris);
5925        }
5926
5927        UriPermission perm = targetUris.get(uri);
5928        if (perm == null) {
5929            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5930            targetUris.put(uri, perm);
5931        }
5932
5933        return perm;
5934    }
5935
5936    private final boolean checkUriPermissionLocked(
5937            Uri uri, int uid, int modeFlags, int minStrength) {
5938        // Root gets to do everything.
5939        if (uid == 0) {
5940            return true;
5941        }
5942        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5943        if (perms == null) return false;
5944        UriPermission perm = perms.get(uri);
5945        if (perm == null) return false;
5946        return perm.getStrength(modeFlags) >= minStrength;
5947    }
5948
5949    @Override
5950    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5951        enforceNotIsolatedCaller("checkUriPermission");
5952
5953        // Another redirected-binder-call permissions check as in
5954        // {@link checkComponentPermission}.
5955        Identity tlsIdentity = sCallerIdentity.get();
5956        if (tlsIdentity != null) {
5957            uid = tlsIdentity.uid;
5958            pid = tlsIdentity.pid;
5959        }
5960
5961        // Our own process gets to do everything.
5962        if (pid == MY_PID) {
5963            return PackageManager.PERMISSION_GRANTED;
5964        }
5965        synchronized(this) {
5966            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5967                    ? PackageManager.PERMISSION_GRANTED
5968                    : PackageManager.PERMISSION_DENIED;
5969        }
5970    }
5971
5972    /**
5973     * Check if the targetPkg can be granted permission to access uri by
5974     * the callingUid using the given modeFlags.  Throws a security exception
5975     * if callingUid is not allowed to do this.  Returns the uid of the target
5976     * if the URI permission grant should be performed; returns -1 if it is not
5977     * needed (for example targetPkg already has permission to access the URI).
5978     * If you already know the uid of the target, you can supply it in
5979     * lastTargetUid else set that to -1.
5980     */
5981    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5982            Uri uri, int modeFlags, int lastTargetUid) {
5983        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5984        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5985                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5986        if (modeFlags == 0) {
5987            return -1;
5988        }
5989
5990        if (targetPkg != null) {
5991            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5992                    "Checking grant " + targetPkg + " permission to " + uri);
5993        }
5994
5995        final IPackageManager pm = AppGlobals.getPackageManager();
5996
5997        // If this is not a content: uri, we can't do anything with it.
5998        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5999            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6000                    "Can't grant URI permission for non-content URI: " + uri);
6001            return -1;
6002        }
6003
6004        final String authority = uri.getAuthority();
6005        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6006        if (pi == null) {
6007            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
6008            return -1;
6009        }
6010
6011        int targetUid = lastTargetUid;
6012        if (targetUid < 0 && targetPkg != null) {
6013            try {
6014                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6015                if (targetUid < 0) {
6016                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6017                            "Can't grant URI permission no uid for: " + targetPkg);
6018                    return -1;
6019                }
6020            } catch (RemoteException ex) {
6021                return -1;
6022            }
6023        }
6024
6025        if (targetUid >= 0) {
6026            // First...  does the target actually need this permission?
6027            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6028                // No need to grant the target this permission.
6029                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6030                        "Target " + targetPkg + " already has full permission to " + uri);
6031                return -1;
6032            }
6033        } else {
6034            // First...  there is no target package, so can anyone access it?
6035            boolean allowed = pi.exported;
6036            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6037                if (pi.readPermission != null) {
6038                    allowed = false;
6039                }
6040            }
6041            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6042                if (pi.writePermission != null) {
6043                    allowed = false;
6044                }
6045            }
6046            if (allowed) {
6047                return -1;
6048            }
6049        }
6050
6051        // Second...  is the provider allowing granting of URI permissions?
6052        if (!pi.grantUriPermissions) {
6053            throw new SecurityException("Provider " + pi.packageName
6054                    + "/" + pi.name
6055                    + " does not allow granting of Uri permissions (uri "
6056                    + uri + ")");
6057        }
6058        if (pi.uriPermissionPatterns != null) {
6059            final int N = pi.uriPermissionPatterns.length;
6060            boolean allowed = false;
6061            for (int i=0; i<N; i++) {
6062                if (pi.uriPermissionPatterns[i] != null
6063                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6064                    allowed = true;
6065                    break;
6066                }
6067            }
6068            if (!allowed) {
6069                throw new SecurityException("Provider " + pi.packageName
6070                        + "/" + pi.name
6071                        + " does not allow granting of permission to path of Uri "
6072                        + uri);
6073            }
6074        }
6075
6076        // Third...  does the caller itself have permission to access
6077        // this uri?
6078        if (callingUid != Process.myUid()) {
6079            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6080                // Require they hold a strong enough Uri permission
6081                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6082                        : UriPermission.STRENGTH_OWNED;
6083                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6084                    throw new SecurityException("Uid " + callingUid
6085                            + " does not have permission to uri " + uri);
6086                }
6087            }
6088        }
6089
6090        return targetUid;
6091    }
6092
6093    @Override
6094    public int checkGrantUriPermission(int callingUid, String targetPkg,
6095            Uri uri, int modeFlags) {
6096        enforceNotIsolatedCaller("checkGrantUriPermission");
6097        synchronized(this) {
6098            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6099        }
6100    }
6101
6102    void grantUriPermissionUncheckedLocked(
6103            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6104        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6105        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6106                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6107        if (modeFlags == 0) {
6108            return;
6109        }
6110
6111        // So here we are: the caller has the assumed permission
6112        // to the uri, and the target doesn't.  Let's now give this to
6113        // the target.
6114
6115        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6116                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6117
6118        final String authority = uri.getAuthority();
6119        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6120        if (pi == null) {
6121            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6122            return;
6123        }
6124
6125        final UriPermission perm = findOrCreateUriPermissionLocked(
6126                pi.packageName, targetPkg, targetUid, uri);
6127        perm.grantModes(modeFlags, persistable, owner);
6128    }
6129
6130    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6131            int modeFlags, UriPermissionOwner owner) {
6132        if (targetPkg == null) {
6133            throw new NullPointerException("targetPkg");
6134        }
6135
6136        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6137        if (targetUid < 0) {
6138            return;
6139        }
6140
6141        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6142    }
6143
6144    static class NeededUriGrants extends ArrayList<Uri> {
6145        final String targetPkg;
6146        final int targetUid;
6147        final int flags;
6148
6149        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6150            this.targetPkg = targetPkg;
6151            this.targetUid = targetUid;
6152            this.flags = flags;
6153        }
6154    }
6155
6156    /**
6157     * Like checkGrantUriPermissionLocked, but takes an Intent.
6158     */
6159    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6160            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6161        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6162                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6163                + " clip=" + (intent != null ? intent.getClipData() : null)
6164                + " from " + intent + "; flags=0x"
6165                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6166
6167        if (targetPkg == null) {
6168            throw new NullPointerException("targetPkg");
6169        }
6170
6171        if (intent == null) {
6172            return null;
6173        }
6174        Uri data = intent.getData();
6175        ClipData clip = intent.getClipData();
6176        if (data == null && clip == null) {
6177            return null;
6178        }
6179
6180        if (data != null) {
6181            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6182                mode, needed != null ? needed.targetUid : -1);
6183            if (targetUid > 0) {
6184                if (needed == null) {
6185                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6186                }
6187                needed.add(data);
6188            }
6189        }
6190        if (clip != null) {
6191            for (int i=0; i<clip.getItemCount(); i++) {
6192                Uri uri = clip.getItemAt(i).getUri();
6193                if (uri != null) {
6194                    int targetUid = -1;
6195                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6196                            mode, needed != null ? needed.targetUid : -1);
6197                    if (targetUid > 0) {
6198                        if (needed == null) {
6199                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6200                        }
6201                        needed.add(uri);
6202                    }
6203                } else {
6204                    Intent clipIntent = clip.getItemAt(i).getIntent();
6205                    if (clipIntent != null) {
6206                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6207                                callingUid, targetPkg, clipIntent, mode, needed);
6208                        if (newNeeded != null) {
6209                            needed = newNeeded;
6210                        }
6211                    }
6212                }
6213            }
6214        }
6215
6216        return needed;
6217    }
6218
6219    /**
6220     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6221     */
6222    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6223            UriPermissionOwner owner) {
6224        if (needed != null) {
6225            for (int i=0; i<needed.size(); i++) {
6226                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6227                        needed.get(i), needed.flags, owner);
6228            }
6229        }
6230    }
6231
6232    void grantUriPermissionFromIntentLocked(int callingUid,
6233            String targetPkg, Intent intent, UriPermissionOwner owner) {
6234        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6235                intent, intent != null ? intent.getFlags() : 0, null);
6236        if (needed == null) {
6237            return;
6238        }
6239
6240        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6241    }
6242
6243    @Override
6244    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6245            Uri uri, int modeFlags) {
6246        enforceNotIsolatedCaller("grantUriPermission");
6247        synchronized(this) {
6248            final ProcessRecord r = getRecordForAppLocked(caller);
6249            if (r == null) {
6250                throw new SecurityException("Unable to find app for caller "
6251                        + caller
6252                        + " when granting permission to uri " + uri);
6253            }
6254            if (targetPkg == null) {
6255                throw new IllegalArgumentException("null target");
6256            }
6257            if (uri == null) {
6258                throw new IllegalArgumentException("null uri");
6259            }
6260
6261            // Persistable only supported through Intents
6262            Preconditions.checkFlagsArgument(modeFlags,
6263                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6264
6265            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6266                    null);
6267        }
6268    }
6269
6270    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6271        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6272                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6273            ArrayMap<Uri, UriPermission> perms
6274                    = mGrantedUriPermissions.get(perm.targetUid);
6275            if (perms != null) {
6276                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6277                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6278                perms.remove(perm.uri);
6279                if (perms.size() == 0) {
6280                    mGrantedUriPermissions.remove(perm.targetUid);
6281                }
6282            }
6283        }
6284    }
6285
6286    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6287        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6288
6289        final IPackageManager pm = AppGlobals.getPackageManager();
6290        final String authority = uri.getAuthority();
6291        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6292        if (pi == null) {
6293            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6294            return;
6295        }
6296
6297        // Does the caller have this permission on the URI?
6298        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6299            // Right now, if you are not the original owner of the permission,
6300            // you are not allowed to revoke it.
6301            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6302                throw new SecurityException("Uid " + callingUid
6303                        + " does not have permission to uri " + uri);
6304            //}
6305        }
6306
6307        boolean persistChanged = false;
6308
6309        // Go through all of the permissions and remove any that match.
6310        final List<String> SEGMENTS = uri.getPathSegments();
6311        if (SEGMENTS != null) {
6312            final int NS = SEGMENTS.size();
6313            int N = mGrantedUriPermissions.size();
6314            for (int i=0; i<N; i++) {
6315                ArrayMap<Uri, UriPermission> perms
6316                        = mGrantedUriPermissions.valueAt(i);
6317                Iterator<UriPermission> it = perms.values().iterator();
6318            toploop:
6319                while (it.hasNext()) {
6320                    UriPermission perm = it.next();
6321                    Uri targetUri = perm.uri;
6322                    if (!authority.equals(targetUri.getAuthority())) {
6323                        continue;
6324                    }
6325                    List<String> targetSegments = targetUri.getPathSegments();
6326                    if (targetSegments == null) {
6327                        continue;
6328                    }
6329                    if (targetSegments.size() < NS) {
6330                        continue;
6331                    }
6332                    for (int j=0; j<NS; j++) {
6333                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6334                            continue toploop;
6335                        }
6336                    }
6337                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6338                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6339                    persistChanged |= perm.clearModes(modeFlags, true);
6340                    if (perm.modeFlags == 0) {
6341                        it.remove();
6342                    }
6343                }
6344                if (perms.size() == 0) {
6345                    mGrantedUriPermissions.remove(
6346                            mGrantedUriPermissions.keyAt(i));
6347                    N--;
6348                    i--;
6349                }
6350            }
6351        }
6352
6353        if (persistChanged) {
6354            schedulePersistUriGrants();
6355        }
6356    }
6357
6358    @Override
6359    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6360            int modeFlags) {
6361        enforceNotIsolatedCaller("revokeUriPermission");
6362        synchronized(this) {
6363            final ProcessRecord r = getRecordForAppLocked(caller);
6364            if (r == null) {
6365                throw new SecurityException("Unable to find app for caller "
6366                        + caller
6367                        + " when revoking permission to uri " + uri);
6368            }
6369            if (uri == null) {
6370                Slog.w(TAG, "revokeUriPermission: null uri");
6371                return;
6372            }
6373
6374            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6375                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6376            if (modeFlags == 0) {
6377                return;
6378            }
6379
6380            final IPackageManager pm = AppGlobals.getPackageManager();
6381            final String authority = uri.getAuthority();
6382            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6383            if (pi == null) {
6384                Slog.w(TAG, "No content provider found for permission revoke: "
6385                        + uri.toSafeString());
6386                return;
6387            }
6388
6389            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6390        }
6391    }
6392
6393    /**
6394     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6395     * given package.
6396     *
6397     * @param packageName Package name to match, or {@code null} to apply to all
6398     *            packages.
6399     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6400     *            to all users.
6401     * @param persistable If persistable grants should be removed.
6402     */
6403    private void removeUriPermissionsForPackageLocked(
6404            String packageName, int userHandle, boolean persistable) {
6405        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6406            throw new IllegalArgumentException("Must narrow by either package or user");
6407        }
6408
6409        boolean persistChanged = false;
6410
6411        final int size = mGrantedUriPermissions.size();
6412        for (int i = 0; i < size; i++) {
6413            // Only inspect grants matching user
6414            if (userHandle == UserHandle.USER_ALL
6415                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6416                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6417                        .values().iterator();
6418                while (it.hasNext()) {
6419                    final UriPermission perm = it.next();
6420
6421                    // Only inspect grants matching package
6422                    if (packageName == null || perm.sourcePkg.equals(packageName)
6423                            || perm.targetPkg.equals(packageName)) {
6424                        persistChanged |= perm.clearModes(~0, persistable);
6425
6426                        // Only remove when no modes remain; any persisted grants
6427                        // will keep this alive.
6428                        if (perm.modeFlags == 0) {
6429                            it.remove();
6430                        }
6431                    }
6432                }
6433            }
6434        }
6435
6436        if (persistChanged) {
6437            schedulePersistUriGrants();
6438        }
6439    }
6440
6441    @Override
6442    public IBinder newUriPermissionOwner(String name) {
6443        enforceNotIsolatedCaller("newUriPermissionOwner");
6444        synchronized(this) {
6445            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6446            return owner.getExternalTokenLocked();
6447        }
6448    }
6449
6450    @Override
6451    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6452            Uri uri, int modeFlags) {
6453        synchronized(this) {
6454            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6455            if (owner == null) {
6456                throw new IllegalArgumentException("Unknown owner: " + token);
6457            }
6458            if (fromUid != Binder.getCallingUid()) {
6459                if (Binder.getCallingUid() != Process.myUid()) {
6460                    // Only system code can grant URI permissions on behalf
6461                    // of other users.
6462                    throw new SecurityException("nice try");
6463                }
6464            }
6465            if (targetPkg == null) {
6466                throw new IllegalArgumentException("null target");
6467            }
6468            if (uri == null) {
6469                throw new IllegalArgumentException("null uri");
6470            }
6471
6472            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6473        }
6474    }
6475
6476    @Override
6477    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6478        synchronized(this) {
6479            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6480            if (owner == null) {
6481                throw new IllegalArgumentException("Unknown owner: " + token);
6482            }
6483
6484            if (uri == null) {
6485                owner.removeUriPermissionsLocked(mode);
6486            } else {
6487                owner.removeUriPermissionLocked(uri, mode);
6488            }
6489        }
6490    }
6491
6492    private void schedulePersistUriGrants() {
6493        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6494            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6495                    10 * DateUtils.SECOND_IN_MILLIS);
6496        }
6497    }
6498
6499    private void writeGrantedUriPermissions() {
6500        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6501
6502        // Snapshot permissions so we can persist without lock
6503        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6504        synchronized (this) {
6505            final int size = mGrantedUriPermissions.size();
6506            for (int i = 0 ; i < size; i++) {
6507                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6508                    if (perm.persistedModeFlags != 0) {
6509                        persist.add(perm.snapshot());
6510                    }
6511                }
6512            }
6513        }
6514
6515        FileOutputStream fos = null;
6516        try {
6517            fos = mGrantFile.startWrite();
6518
6519            XmlSerializer out = new FastXmlSerializer();
6520            out.setOutput(fos, "utf-8");
6521            out.startDocument(null, true);
6522            out.startTag(null, TAG_URI_GRANTS);
6523            for (UriPermission.Snapshot perm : persist) {
6524                out.startTag(null, TAG_URI_GRANT);
6525                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6526                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6527                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6528                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6529                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6530                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6531                out.endTag(null, TAG_URI_GRANT);
6532            }
6533            out.endTag(null, TAG_URI_GRANTS);
6534            out.endDocument();
6535
6536            mGrantFile.finishWrite(fos);
6537        } catch (IOException e) {
6538            if (fos != null) {
6539                mGrantFile.failWrite(fos);
6540            }
6541        }
6542    }
6543
6544    private void readGrantedUriPermissionsLocked() {
6545        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6546
6547        final long now = System.currentTimeMillis();
6548
6549        FileInputStream fis = null;
6550        try {
6551            fis = mGrantFile.openRead();
6552            final XmlPullParser in = Xml.newPullParser();
6553            in.setInput(fis, null);
6554
6555            int type;
6556            while ((type = in.next()) != END_DOCUMENT) {
6557                final String tag = in.getName();
6558                if (type == START_TAG) {
6559                    if (TAG_URI_GRANT.equals(tag)) {
6560                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6561                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6562                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6563                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6564                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6565                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6566
6567                        // Sanity check that provider still belongs to source package
6568                        final ProviderInfo pi = getProviderInfoLocked(
6569                                uri.getAuthority(), userHandle);
6570                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6571                            int targetUid = -1;
6572                            try {
6573                                targetUid = AppGlobals.getPackageManager()
6574                                        .getPackageUid(targetPkg, userHandle);
6575                            } catch (RemoteException e) {
6576                            }
6577                            if (targetUid != -1) {
6578                                final UriPermission perm = findOrCreateUriPermissionLocked(
6579                                        sourcePkg, targetPkg, targetUid, uri);
6580                                perm.initPersistedModes(modeFlags, createdTime);
6581                            }
6582                        } else {
6583                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6584                                    + " but instead found " + pi);
6585                        }
6586                    }
6587                }
6588            }
6589        } catch (FileNotFoundException e) {
6590            // Missing grants is okay
6591        } catch (IOException e) {
6592            Log.wtf(TAG, "Failed reading Uri grants", e);
6593        } catch (XmlPullParserException e) {
6594            Log.wtf(TAG, "Failed reading Uri grants", e);
6595        } finally {
6596            IoUtils.closeQuietly(fis);
6597        }
6598    }
6599
6600    @Override
6601    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6602        enforceNotIsolatedCaller("takePersistableUriPermission");
6603
6604        Preconditions.checkFlagsArgument(modeFlags,
6605                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6606
6607        synchronized (this) {
6608            final int callingUid = Binder.getCallingUid();
6609            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6610            if (perm == null) {
6611                throw new SecurityException("No permission grant found for UID " + callingUid
6612                        + " and Uri " + uri.toSafeString());
6613            }
6614
6615            boolean persistChanged = perm.takePersistableModes(modeFlags);
6616            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6617
6618            if (persistChanged) {
6619                schedulePersistUriGrants();
6620            }
6621        }
6622    }
6623
6624    @Override
6625    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6626        enforceNotIsolatedCaller("releasePersistableUriPermission");
6627
6628        Preconditions.checkFlagsArgument(modeFlags,
6629                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6630
6631        synchronized (this) {
6632            final int callingUid = Binder.getCallingUid();
6633
6634            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6635            if (perm == null) {
6636                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6637                        + uri.toSafeString());
6638                return;
6639            }
6640
6641            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6642            removeUriPermissionIfNeededLocked(perm);
6643            if (persistChanged) {
6644                schedulePersistUriGrants();
6645            }
6646        }
6647    }
6648
6649    /**
6650     * Prune any older {@link UriPermission} for the given UID until outstanding
6651     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6652     *
6653     * @return if any mutations occured that require persisting.
6654     */
6655    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6656        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6657        if (perms == null) return false;
6658        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6659
6660        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6661        for (UriPermission perm : perms.values()) {
6662            if (perm.persistedModeFlags != 0) {
6663                persisted.add(perm);
6664            }
6665        }
6666
6667        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6668        if (trimCount <= 0) return false;
6669
6670        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6671        for (int i = 0; i < trimCount; i++) {
6672            final UriPermission perm = persisted.get(i);
6673
6674            if (DEBUG_URI_PERMISSION) {
6675                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6676            }
6677
6678            perm.releasePersistableModes(~0);
6679            removeUriPermissionIfNeededLocked(perm);
6680        }
6681
6682        return true;
6683    }
6684
6685    @Override
6686    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6687            String packageName, boolean incoming) {
6688        enforceNotIsolatedCaller("getPersistedUriPermissions");
6689        Preconditions.checkNotNull(packageName, "packageName");
6690
6691        final int callingUid = Binder.getCallingUid();
6692        final IPackageManager pm = AppGlobals.getPackageManager();
6693        try {
6694            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6695            if (packageUid != callingUid) {
6696                throw new SecurityException(
6697                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6698            }
6699        } catch (RemoteException e) {
6700            throw new SecurityException("Failed to verify package name ownership");
6701        }
6702
6703        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6704        synchronized (this) {
6705            if (incoming) {
6706                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6707                if (perms == null) {
6708                    Slog.w(TAG, "No permission grants found for " + packageName);
6709                } else {
6710                    final int size = perms.size();
6711                    for (int i = 0; i < size; i++) {
6712                        final UriPermission perm = perms.valueAt(i);
6713                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6714                            result.add(perm.buildPersistedPublicApiObject());
6715                        }
6716                    }
6717                }
6718            } else {
6719                final int size = mGrantedUriPermissions.size();
6720                for (int i = 0; i < size; i++) {
6721                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6722                    final int permsSize = perms.size();
6723                    for (int j = 0; j < permsSize; j++) {
6724                        final UriPermission perm = perms.valueAt(j);
6725                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6726                            result.add(perm.buildPersistedPublicApiObject());
6727                        }
6728                    }
6729                }
6730            }
6731        }
6732        return new ParceledListSlice<android.content.UriPermission>(result);
6733    }
6734
6735    @Override
6736    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6737        synchronized (this) {
6738            ProcessRecord app =
6739                who != null ? getRecordForAppLocked(who) : null;
6740            if (app == null) return;
6741
6742            Message msg = Message.obtain();
6743            msg.what = WAIT_FOR_DEBUGGER_MSG;
6744            msg.obj = app;
6745            msg.arg1 = waiting ? 1 : 0;
6746            mHandler.sendMessage(msg);
6747        }
6748    }
6749
6750    @Override
6751    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6752        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6753        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6754        outInfo.availMem = Process.getFreeMemory();
6755        outInfo.totalMem = Process.getTotalMemory();
6756        outInfo.threshold = homeAppMem;
6757        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6758        outInfo.hiddenAppThreshold = cachedAppMem;
6759        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6760                ProcessList.SERVICE_ADJ);
6761        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6762                ProcessList.VISIBLE_APP_ADJ);
6763        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6764                ProcessList.FOREGROUND_APP_ADJ);
6765    }
6766
6767    // =========================================================
6768    // TASK MANAGEMENT
6769    // =========================================================
6770
6771    @Override
6772    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6773                         IThumbnailReceiver receiver) {
6774        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6775
6776        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6777        ActivityRecord topRecord = null;
6778
6779        synchronized(this) {
6780            if (localLOGV) Slog.v(
6781                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6782                + ", receiver=" + receiver);
6783
6784            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6785                    != PackageManager.PERMISSION_GRANTED) {
6786                if (receiver != null) {
6787                    // If the caller wants to wait for pending thumbnails,
6788                    // it ain't gonna get them.
6789                    try {
6790                        receiver.finished();
6791                    } catch (RemoteException ex) {
6792                    }
6793                }
6794                String msg = "Permission Denial: getTasks() from pid="
6795                        + Binder.getCallingPid()
6796                        + ", uid=" + Binder.getCallingUid()
6797                        + " requires " + android.Manifest.permission.GET_TASKS;
6798                Slog.w(TAG, msg);
6799                throw new SecurityException(msg);
6800            }
6801
6802            // TODO: Improve with MRU list from all ActivityStacks.
6803            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6804
6805            if (!pending.pendingRecords.isEmpty()) {
6806                mPendingThumbnails.add(pending);
6807            }
6808        }
6809
6810        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6811
6812        if (topRecord != null) {
6813            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6814            try {
6815                IApplicationThread topThumbnail = topRecord.app.thread;
6816                topThumbnail.requestThumbnail(topRecord.appToken);
6817            } catch (Exception e) {
6818                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6819                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6820            }
6821        }
6822
6823        if (pending == null && receiver != null) {
6824            // In this case all thumbnails were available and the client
6825            // is being asked to be told when the remaining ones come in...
6826            // which is unusually, since the top-most currently running
6827            // activity should never have a canned thumbnail!  Oh well.
6828            try {
6829                receiver.finished();
6830            } catch (RemoteException ex) {
6831            }
6832        }
6833
6834        return list;
6835    }
6836
6837    TaskRecord getMostRecentTask() {
6838        return mRecentTasks.get(0);
6839    }
6840
6841    @Override
6842    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6843            int flags, int userId) {
6844        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6845                false, true, "getRecentTasks", null);
6846
6847        synchronized (this) {
6848            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6849                    "getRecentTasks()");
6850            final boolean detailed = checkCallingPermission(
6851                    android.Manifest.permission.GET_DETAILED_TASKS)
6852                    == PackageManager.PERMISSION_GRANTED;
6853
6854            IPackageManager pm = AppGlobals.getPackageManager();
6855
6856            final int N = mRecentTasks.size();
6857            ArrayList<ActivityManager.RecentTaskInfo> res
6858                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6859                            maxNum < N ? maxNum : N);
6860
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                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6899                        // Check whether this activity is currently available.
6900                        try {
6901                            if (rti.origActivity != null) {
6902                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6903                                        == null) {
6904                                    continue;
6905                                }
6906                            } else if (rti.baseIntent != null) {
6907                                if (pm.queryIntentActivities(rti.baseIntent,
6908                                        null, 0, userId) == null) {
6909                                    continue;
6910                                }
6911                            }
6912                        } catch (RemoteException e) {
6913                            // Will never happen.
6914                        }
6915                    }
6916
6917                    res.add(rti);
6918                    maxNum--;
6919                }
6920            }
6921            return res;
6922        }
6923    }
6924
6925    private TaskRecord recentTaskForIdLocked(int id) {
6926        final int N = mRecentTasks.size();
6927            for (int i=0; i<N; i++) {
6928                TaskRecord tr = mRecentTasks.get(i);
6929                if (tr.taskId == id) {
6930                    return tr;
6931                }
6932            }
6933            return null;
6934    }
6935
6936    @Override
6937    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6938        synchronized (this) {
6939            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6940                    "getTaskThumbnails()");
6941            TaskRecord tr = recentTaskForIdLocked(id);
6942            if (tr != null) {
6943                return tr.getTaskThumbnailsLocked();
6944            }
6945        }
6946        return null;
6947    }
6948
6949    @Override
6950    public Bitmap getTaskTopThumbnail(int id) {
6951        synchronized (this) {
6952            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6953                    "getTaskTopThumbnail()");
6954            TaskRecord tr = recentTaskForIdLocked(id);
6955            if (tr != null) {
6956                return tr.getTaskTopThumbnailLocked();
6957            }
6958        }
6959        return null;
6960    }
6961
6962    @Override
6963    public boolean removeSubTask(int taskId, int subTaskIndex) {
6964        synchronized (this) {
6965            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6966                    "removeSubTask()");
6967            long ident = Binder.clearCallingIdentity();
6968            try {
6969                TaskRecord tr = recentTaskForIdLocked(taskId);
6970                if (tr != null) {
6971                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6972                }
6973                return false;
6974            } finally {
6975                Binder.restoreCallingIdentity(ident);
6976            }
6977        }
6978    }
6979
6980    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6981        if (!pr.killedByAm) {
6982            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6983            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6984                    pr.processName, pr.setAdj, reason);
6985            pr.killedByAm = true;
6986            Process.killProcessQuiet(pr.pid);
6987        }
6988    }
6989
6990    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6991        tr.disposeThumbnail();
6992        mRecentTasks.remove(tr);
6993        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6994        Intent baseIntent = new Intent(
6995                tr.intent != null ? tr.intent : tr.affinityIntent);
6996        ComponentName component = baseIntent.getComponent();
6997        if (component == null) {
6998            Slog.w(TAG, "Now component for base intent of task: " + tr);
6999            return;
7000        }
7001
7002        // Find any running services associated with this app.
7003        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7004
7005        if (killProcesses) {
7006            // Find any running processes associated with this app.
7007            final String pkg = component.getPackageName();
7008            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7009            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7010            for (int i=0; i<pmap.size(); i++) {
7011                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7012                for (int j=0; j<uids.size(); j++) {
7013                    ProcessRecord proc = uids.valueAt(j);
7014                    if (proc.userId != tr.userId) {
7015                        continue;
7016                    }
7017                    if (!proc.pkgList.containsKey(pkg)) {
7018                        continue;
7019                    }
7020                    procs.add(proc);
7021                }
7022            }
7023
7024            // Kill the running processes.
7025            for (int i=0; i<procs.size(); i++) {
7026                ProcessRecord pr = procs.get(i);
7027                if (pr == mHomeProcess) {
7028                    // Don't kill the home process along with tasks from the same package.
7029                    continue;
7030                }
7031                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7032                    killUnneededProcessLocked(pr, "remove task");
7033                } else {
7034                    pr.waitingToKill = "remove task";
7035                }
7036            }
7037        }
7038    }
7039
7040    @Override
7041    public boolean removeTask(int taskId, int flags) {
7042        synchronized (this) {
7043            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7044                    "removeTask()");
7045            long ident = Binder.clearCallingIdentity();
7046            try {
7047                TaskRecord tr = recentTaskForIdLocked(taskId);
7048                if (tr != null) {
7049                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7050                    if (r != null) {
7051                        cleanUpRemovedTaskLocked(tr, flags);
7052                        return true;
7053                    }
7054                    if (tr.mActivities.size() == 0) {
7055                        // Caller is just removing a recent task that is
7056                        // not actively running.  That is easy!
7057                        cleanUpRemovedTaskLocked(tr, flags);
7058                        return true;
7059                    }
7060                    Slog.w(TAG, "removeTask: task " + taskId
7061                            + " does not have activities to remove, "
7062                            + " but numActivities=" + tr.numActivities
7063                            + ": " + tr);
7064                }
7065            } finally {
7066                Binder.restoreCallingIdentity(ident);
7067            }
7068        }
7069        return false;
7070    }
7071
7072    /**
7073     * TODO: Add mController hook
7074     */
7075    @Override
7076    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7077        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7078                "moveTaskToFront()");
7079
7080        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7081        synchronized(this) {
7082            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7083                    Binder.getCallingUid(), "Task to front")) {
7084                ActivityOptions.abort(options);
7085                return;
7086            }
7087            final long origId = Binder.clearCallingIdentity();
7088            try {
7089                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7090                if (task == null) {
7091                    return;
7092                }
7093                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7094                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7095                    return;
7096                }
7097                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7098            } finally {
7099                Binder.restoreCallingIdentity(origId);
7100            }
7101            ActivityOptions.abort(options);
7102        }
7103    }
7104
7105    @Override
7106    public void moveTaskToBack(int taskId) {
7107        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7108                "moveTaskToBack()");
7109
7110        synchronized(this) {
7111            TaskRecord tr = recentTaskForIdLocked(taskId);
7112            if (tr != null) {
7113                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7114                ActivityStack stack = tr.stack;
7115                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7116                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7117                            Binder.getCallingUid(), "Task to back")) {
7118                        return;
7119                    }
7120                }
7121                final long origId = Binder.clearCallingIdentity();
7122                try {
7123                    stack.moveTaskToBackLocked(taskId, null);
7124                } finally {
7125                    Binder.restoreCallingIdentity(origId);
7126                }
7127            }
7128        }
7129    }
7130
7131    /**
7132     * Moves an activity, and all of the other activities within the same task, to the bottom
7133     * of the history stack.  The activity's order within the task is unchanged.
7134     *
7135     * @param token A reference to the activity we wish to move
7136     * @param nonRoot If false then this only works if the activity is the root
7137     *                of a task; if true it will work for any activity in a task.
7138     * @return Returns true if the move completed, false if not.
7139     */
7140    @Override
7141    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7142        enforceNotIsolatedCaller("moveActivityTaskToBack");
7143        synchronized(this) {
7144            final long origId = Binder.clearCallingIdentity();
7145            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7146            if (taskId >= 0) {
7147                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7148            }
7149            Binder.restoreCallingIdentity(origId);
7150        }
7151        return false;
7152    }
7153
7154    @Override
7155    public void moveTaskBackwards(int task) {
7156        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7157                "moveTaskBackwards()");
7158
7159        synchronized(this) {
7160            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7161                    Binder.getCallingUid(), "Task backwards")) {
7162                return;
7163            }
7164            final long origId = Binder.clearCallingIdentity();
7165            moveTaskBackwardsLocked(task);
7166            Binder.restoreCallingIdentity(origId);
7167        }
7168    }
7169
7170    private final void moveTaskBackwardsLocked(int task) {
7171        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7172    }
7173
7174    @Override
7175    public IBinder getHomeActivityToken() throws RemoteException {
7176        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7177                "getHomeActivityToken()");
7178        synchronized (this) {
7179            return mStackSupervisor.getHomeActivityToken();
7180        }
7181    }
7182
7183    @Override
7184    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7185            IActivityContainerCallback callback) throws RemoteException {
7186        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7187                "createActivityContainer()");
7188        synchronized (this) {
7189            if (parentActivityToken == null) {
7190                throw new IllegalArgumentException("parent token must not be null");
7191            }
7192            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7193            if (r == null) {
7194                return null;
7195            }
7196            return mStackSupervisor.createActivityContainer(r, callback);
7197        }
7198    }
7199
7200    @Override
7201    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7202        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7203                "deleteActivityContainer()");
7204        synchronized (this) {
7205            mStackSupervisor.deleteActivityContainer(container);
7206        }
7207    }
7208
7209    @Override
7210    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7211            throws RemoteException {
7212        synchronized (this) {
7213            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7214            if (stack != null) {
7215                return stack.mActivityContainer;
7216            }
7217            return null;
7218        }
7219    }
7220
7221    @Override
7222    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7223        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7224                "moveTaskToStack()");
7225        if (stackId == HOME_STACK_ID) {
7226            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7227                    new RuntimeException("here").fillInStackTrace());
7228        }
7229        synchronized (this) {
7230            long ident = Binder.clearCallingIdentity();
7231            try {
7232                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7233                        + stackId + " toTop=" + toTop);
7234                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7235            } finally {
7236                Binder.restoreCallingIdentity(ident);
7237            }
7238        }
7239    }
7240
7241    @Override
7242    public void resizeStack(int stackBoxId, Rect bounds) {
7243        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7244                "resizeStackBox()");
7245        long ident = Binder.clearCallingIdentity();
7246        try {
7247            mWindowManager.resizeStack(stackBoxId, bounds);
7248        } finally {
7249            Binder.restoreCallingIdentity(ident);
7250        }
7251    }
7252
7253    @Override
7254    public List<StackInfo> getAllStackInfos() {
7255        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7256                "getAllStackInfos()");
7257        long ident = Binder.clearCallingIdentity();
7258        try {
7259            synchronized (this) {
7260                return mStackSupervisor.getAllStackInfosLocked();
7261            }
7262        } finally {
7263            Binder.restoreCallingIdentity(ident);
7264        }
7265    }
7266
7267    @Override
7268    public StackInfo getStackInfo(int stackId) {
7269        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7270                "getStackInfo()");
7271        long ident = Binder.clearCallingIdentity();
7272        try {
7273            synchronized (this) {
7274                return mStackSupervisor.getStackInfoLocked(stackId);
7275            }
7276        } finally {
7277            Binder.restoreCallingIdentity(ident);
7278        }
7279    }
7280
7281    @Override
7282    public boolean isInHomeStack(int taskId) {
7283        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7284                "getStackInfo()");
7285        long ident = Binder.clearCallingIdentity();
7286        try {
7287            synchronized (this) {
7288                TaskRecord tr = recentTaskForIdLocked(taskId);
7289                if (tr != null) {
7290                    return tr.stack.isHomeStack();
7291                }
7292            }
7293        } finally {
7294            Binder.restoreCallingIdentity(ident);
7295        }
7296        return false;
7297    }
7298
7299    @Override
7300    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7301        synchronized(this) {
7302            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7303        }
7304    }
7305
7306    private boolean isLockTaskAuthorized(ComponentName name) {
7307//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7308//                "startLockTaskMode()");
7309//        DevicePolicyManager dpm = (DevicePolicyManager)
7310//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7311//        return dpm != null && dpm.isLockTaskPermitted(name);
7312        return true;
7313    }
7314
7315    private void startLockTaskMode(TaskRecord task) {
7316        if (!isLockTaskAuthorized(task.intent.getComponent())) {
7317            return;
7318        }
7319        long ident = Binder.clearCallingIdentity();
7320        try {
7321            synchronized (this) {
7322                // Since we lost lock on task, make sure it is still there.
7323                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7324                if (task != null) {
7325                    mStackSupervisor.setLockTaskModeLocked(task);
7326                }
7327            }
7328        } finally {
7329            Binder.restoreCallingIdentity(ident);
7330        }
7331    }
7332
7333    @Override
7334    public void startLockTaskMode(int taskId) {
7335        long ident = Binder.clearCallingIdentity();
7336        try {
7337            final TaskRecord task;
7338            synchronized (this) {
7339                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7340            }
7341            if (task != null) {
7342                startLockTaskMode(task);
7343            }
7344        } finally {
7345            Binder.restoreCallingIdentity(ident);
7346        }
7347    }
7348
7349    @Override
7350    public void startLockTaskMode(IBinder token) {
7351        long ident = Binder.clearCallingIdentity();
7352        try {
7353            final TaskRecord task;
7354            synchronized (this) {
7355                final ActivityRecord r = ActivityRecord.forToken(token);
7356                if (r == null) {
7357                    return;
7358                }
7359                task = r.task;
7360            }
7361            if (task != null) {
7362                startLockTaskMode(task);
7363            }
7364        } finally {
7365            Binder.restoreCallingIdentity(ident);
7366        }
7367    }
7368
7369    @Override
7370    public void stopLockTaskMode() {
7371//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7372//                "stopLockTaskMode()");
7373        synchronized (this) {
7374            mStackSupervisor.setLockTaskModeLocked(null);
7375        }
7376    }
7377
7378    @Override
7379    public boolean isInLockTaskMode() {
7380        synchronized (this) {
7381            return mStackSupervisor.isInLockTaskMode();
7382        }
7383    }
7384
7385    // =========================================================
7386    // THUMBNAILS
7387    // =========================================================
7388
7389    public void reportThumbnail(IBinder token,
7390            Bitmap thumbnail, CharSequence description) {
7391        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7392        final long origId = Binder.clearCallingIdentity();
7393        sendPendingThumbnail(null, token, thumbnail, description, true);
7394        Binder.restoreCallingIdentity(origId);
7395    }
7396
7397    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7398            Bitmap thumbnail, CharSequence description, boolean always) {
7399        TaskRecord task;
7400        ArrayList<PendingThumbnailsRecord> receivers = null;
7401
7402        //System.out.println("Send pending thumbnail: " + r);
7403
7404        synchronized(this) {
7405            if (r == null) {
7406                r = ActivityRecord.isInStackLocked(token);
7407                if (r == null) {
7408                    return;
7409                }
7410            }
7411            if (thumbnail == null && r.thumbHolder != null) {
7412                thumbnail = r.thumbHolder.lastThumbnail;
7413                description = r.thumbHolder.lastDescription;
7414            }
7415            if (thumbnail == null && !always) {
7416                // If there is no thumbnail, and this entry is not actually
7417                // going away, then abort for now and pick up the next
7418                // thumbnail we get.
7419                return;
7420            }
7421            task = r.task;
7422
7423            int N = mPendingThumbnails.size();
7424            int i=0;
7425            while (i<N) {
7426                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7427                //System.out.println("Looking in " + pr.pendingRecords);
7428                if (pr.pendingRecords.remove(r)) {
7429                    if (receivers == null) {
7430                        receivers = new ArrayList<PendingThumbnailsRecord>();
7431                    }
7432                    receivers.add(pr);
7433                    if (pr.pendingRecords.size() == 0) {
7434                        pr.finished = true;
7435                        mPendingThumbnails.remove(i);
7436                        N--;
7437                        continue;
7438                    }
7439                }
7440                i++;
7441            }
7442        }
7443
7444        if (receivers != null) {
7445            final int N = receivers.size();
7446            for (int i=0; i<N; i++) {
7447                try {
7448                    PendingThumbnailsRecord pr = receivers.get(i);
7449                    pr.receiver.newThumbnail(
7450                        task != null ? task.taskId : -1, thumbnail, description);
7451                    if (pr.finished) {
7452                        pr.receiver.finished();
7453                    }
7454                } catch (Exception e) {
7455                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7456                }
7457            }
7458        }
7459    }
7460
7461    // =========================================================
7462    // CONTENT PROVIDERS
7463    // =========================================================
7464
7465    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7466        List<ProviderInfo> providers = null;
7467        try {
7468            providers = AppGlobals.getPackageManager().
7469                queryContentProviders(app.processName, app.uid,
7470                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7471        } catch (RemoteException ex) {
7472        }
7473        if (DEBUG_MU)
7474            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7475        int userId = app.userId;
7476        if (providers != null) {
7477            int N = providers.size();
7478            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7479            for (int i=0; i<N; i++) {
7480                ProviderInfo cpi =
7481                    (ProviderInfo)providers.get(i);
7482                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7483                        cpi.name, cpi.flags);
7484                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7485                    // This is a singleton provider, but a user besides the
7486                    // default user is asking to initialize a process it runs
7487                    // in...  well, no, it doesn't actually run in this process,
7488                    // it runs in the process of the default user.  Get rid of it.
7489                    providers.remove(i);
7490                    N--;
7491                    i--;
7492                    continue;
7493                }
7494
7495                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7496                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7497                if (cpr == null) {
7498                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7499                    mProviderMap.putProviderByClass(comp, cpr);
7500                }
7501                if (DEBUG_MU)
7502                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7503                app.pubProviders.put(cpi.name, cpr);
7504                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7505                    // Don't add this if it is a platform component that is marked
7506                    // to run in multiple processes, because this is actually
7507                    // part of the framework so doesn't make sense to track as a
7508                    // separate apk in the process.
7509                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7510                }
7511                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7512            }
7513        }
7514        return providers;
7515    }
7516
7517    /**
7518     * Check if {@link ProcessRecord} has a possible chance at accessing the
7519     * given {@link ProviderInfo}. Final permission checking is always done
7520     * in {@link ContentProvider}.
7521     */
7522    private final String checkContentProviderPermissionLocked(
7523            ProviderInfo cpi, ProcessRecord r) {
7524        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7525        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7526        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7527                cpi.applicationInfo.uid, cpi.exported)
7528                == PackageManager.PERMISSION_GRANTED) {
7529            return null;
7530        }
7531        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7532                cpi.applicationInfo.uid, cpi.exported)
7533                == PackageManager.PERMISSION_GRANTED) {
7534            return null;
7535        }
7536
7537        PathPermission[] pps = cpi.pathPermissions;
7538        if (pps != null) {
7539            int i = pps.length;
7540            while (i > 0) {
7541                i--;
7542                PathPermission pp = pps[i];
7543                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7544                        cpi.applicationInfo.uid, cpi.exported)
7545                        == PackageManager.PERMISSION_GRANTED) {
7546                    return null;
7547                }
7548                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7549                        cpi.applicationInfo.uid, cpi.exported)
7550                        == PackageManager.PERMISSION_GRANTED) {
7551                    return null;
7552                }
7553            }
7554        }
7555
7556        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7557        if (perms != null) {
7558            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7559                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7560                    return null;
7561                }
7562            }
7563        }
7564
7565        String msg;
7566        if (!cpi.exported) {
7567            msg = "Permission Denial: opening provider " + cpi.name
7568                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7569                    + ", uid=" + callingUid + ") that is not exported from uid "
7570                    + cpi.applicationInfo.uid;
7571        } else {
7572            msg = "Permission Denial: opening provider " + cpi.name
7573                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7574                    + ", uid=" + callingUid + ") requires "
7575                    + cpi.readPermission + " or " + cpi.writePermission;
7576        }
7577        Slog.w(TAG, msg);
7578        return msg;
7579    }
7580
7581    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7582            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7583        if (r != null) {
7584            for (int i=0; i<r.conProviders.size(); i++) {
7585                ContentProviderConnection conn = r.conProviders.get(i);
7586                if (conn.provider == cpr) {
7587                    if (DEBUG_PROVIDER) Slog.v(TAG,
7588                            "Adding provider requested by "
7589                            + r.processName + " from process "
7590                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7591                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7592                    if (stable) {
7593                        conn.stableCount++;
7594                        conn.numStableIncs++;
7595                    } else {
7596                        conn.unstableCount++;
7597                        conn.numUnstableIncs++;
7598                    }
7599                    return conn;
7600                }
7601            }
7602            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7603            if (stable) {
7604                conn.stableCount = 1;
7605                conn.numStableIncs = 1;
7606            } else {
7607                conn.unstableCount = 1;
7608                conn.numUnstableIncs = 1;
7609            }
7610            cpr.connections.add(conn);
7611            r.conProviders.add(conn);
7612            return conn;
7613        }
7614        cpr.addExternalProcessHandleLocked(externalProcessToken);
7615        return null;
7616    }
7617
7618    boolean decProviderCountLocked(ContentProviderConnection conn,
7619            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7620        if (conn != null) {
7621            cpr = conn.provider;
7622            if (DEBUG_PROVIDER) Slog.v(TAG,
7623                    "Removing provider requested by "
7624                    + conn.client.processName + " from process "
7625                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7626                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7627            if (stable) {
7628                conn.stableCount--;
7629            } else {
7630                conn.unstableCount--;
7631            }
7632            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7633                cpr.connections.remove(conn);
7634                conn.client.conProviders.remove(conn);
7635                return true;
7636            }
7637            return false;
7638        }
7639        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7640        return false;
7641    }
7642
7643    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7644            String name, IBinder token, boolean stable, int userId) {
7645        ContentProviderRecord cpr;
7646        ContentProviderConnection conn = null;
7647        ProviderInfo cpi = null;
7648
7649        synchronized(this) {
7650            ProcessRecord r = null;
7651            if (caller != null) {
7652                r = getRecordForAppLocked(caller);
7653                if (r == null) {
7654                    throw new SecurityException(
7655                            "Unable to find app for caller " + caller
7656                          + " (pid=" + Binder.getCallingPid()
7657                          + ") when getting content provider " + name);
7658                }
7659            }
7660
7661            // First check if this content provider has been published...
7662            cpr = mProviderMap.getProviderByName(name, userId);
7663            boolean providerRunning = cpr != null;
7664            if (providerRunning) {
7665                cpi = cpr.info;
7666                String msg;
7667                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7668                    throw new SecurityException(msg);
7669                }
7670
7671                if (r != null && cpr.canRunHere(r)) {
7672                    // This provider has been published or is in the process
7673                    // of being published...  but it is also allowed to run
7674                    // in the caller's process, so don't make a connection
7675                    // and just let the caller instantiate its own instance.
7676                    ContentProviderHolder holder = cpr.newHolder(null);
7677                    // don't give caller the provider object, it needs
7678                    // to make its own.
7679                    holder.provider = null;
7680                    return holder;
7681                }
7682
7683                final long origId = Binder.clearCallingIdentity();
7684
7685                // In this case the provider instance already exists, so we can
7686                // return it right away.
7687                conn = incProviderCountLocked(r, cpr, token, stable);
7688                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7689                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7690                        // If this is a perceptible app accessing the provider,
7691                        // make sure to count it as being accessed and thus
7692                        // back up on the LRU list.  This is good because
7693                        // content providers are often expensive to start.
7694                        updateLruProcessLocked(cpr.proc, false, null);
7695                    }
7696                }
7697
7698                if (cpr.proc != null) {
7699                    if (false) {
7700                        if (cpr.name.flattenToShortString().equals(
7701                                "com.android.providers.calendar/.CalendarProvider2")) {
7702                            Slog.v(TAG, "****************** KILLING "
7703                                + cpr.name.flattenToShortString());
7704                            Process.killProcess(cpr.proc.pid);
7705                        }
7706                    }
7707                    boolean success = updateOomAdjLocked(cpr.proc);
7708                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7709                    // NOTE: there is still a race here where a signal could be
7710                    // pending on the process even though we managed to update its
7711                    // adj level.  Not sure what to do about this, but at least
7712                    // the race is now smaller.
7713                    if (!success) {
7714                        // Uh oh...  it looks like the provider's process
7715                        // has been killed on us.  We need to wait for a new
7716                        // process to be started, and make sure its death
7717                        // doesn't kill our process.
7718                        Slog.i(TAG,
7719                                "Existing provider " + cpr.name.flattenToShortString()
7720                                + " is crashing; detaching " + r);
7721                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7722                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7723                        if (!lastRef) {
7724                            // This wasn't the last ref our process had on
7725                            // the provider...  we have now been killed, bail.
7726                            return null;
7727                        }
7728                        providerRunning = false;
7729                        conn = null;
7730                    }
7731                }
7732
7733                Binder.restoreCallingIdentity(origId);
7734            }
7735
7736            boolean singleton;
7737            if (!providerRunning) {
7738                try {
7739                    cpi = AppGlobals.getPackageManager().
7740                        resolveContentProvider(name,
7741                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7742                } catch (RemoteException ex) {
7743                }
7744                if (cpi == null) {
7745                    return null;
7746                }
7747                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7748                        cpi.name, cpi.flags);
7749                if (singleton) {
7750                    userId = 0;
7751                }
7752                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7753
7754                String msg;
7755                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7756                    throw new SecurityException(msg);
7757                }
7758
7759                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7760                        && !cpi.processName.equals("system")) {
7761                    // If this content provider does not run in the system
7762                    // process, and the system is not yet ready to run other
7763                    // processes, then fail fast instead of hanging.
7764                    throw new IllegalArgumentException(
7765                            "Attempt to launch content provider before system ready");
7766                }
7767
7768                // Make sure that the user who owns this provider is started.  If not,
7769                // we don't want to allow it to run.
7770                if (mStartedUsers.get(userId) == null) {
7771                    Slog.w(TAG, "Unable to launch app "
7772                            + cpi.applicationInfo.packageName + "/"
7773                            + cpi.applicationInfo.uid + " for provider "
7774                            + name + ": user " + userId + " is stopped");
7775                    return null;
7776                }
7777
7778                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7779                cpr = mProviderMap.getProviderByClass(comp, userId);
7780                final boolean firstClass = cpr == null;
7781                if (firstClass) {
7782                    try {
7783                        ApplicationInfo ai =
7784                            AppGlobals.getPackageManager().
7785                                getApplicationInfo(
7786                                        cpi.applicationInfo.packageName,
7787                                        STOCK_PM_FLAGS, userId);
7788                        if (ai == null) {
7789                            Slog.w(TAG, "No package info for content provider "
7790                                    + cpi.name);
7791                            return null;
7792                        }
7793                        ai = getAppInfoForUser(ai, userId);
7794                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7795                    } catch (RemoteException ex) {
7796                        // pm is in same process, this will never happen.
7797                    }
7798                }
7799
7800                if (r != null && cpr.canRunHere(r)) {
7801                    // If this is a multiprocess provider, then just return its
7802                    // info and allow the caller to instantiate it.  Only do
7803                    // this if the provider is the same user as the caller's
7804                    // process, or can run as root (so can be in any process).
7805                    return cpr.newHolder(null);
7806                }
7807
7808                if (DEBUG_PROVIDER) {
7809                    RuntimeException e = new RuntimeException("here");
7810                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7811                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7812                }
7813
7814                // This is single process, and our app is now connecting to it.
7815                // See if we are already in the process of launching this
7816                // provider.
7817                final int N = mLaunchingProviders.size();
7818                int i;
7819                for (i=0; i<N; i++) {
7820                    if (mLaunchingProviders.get(i) == cpr) {
7821                        break;
7822                    }
7823                }
7824
7825                // If the provider is not already being launched, then get it
7826                // started.
7827                if (i >= N) {
7828                    final long origId = Binder.clearCallingIdentity();
7829
7830                    try {
7831                        // Content provider is now in use, its package can't be stopped.
7832                        try {
7833                            AppGlobals.getPackageManager().setPackageStoppedState(
7834                                    cpr.appInfo.packageName, false, userId);
7835                        } catch (RemoteException e) {
7836                        } catch (IllegalArgumentException e) {
7837                            Slog.w(TAG, "Failed trying to unstop package "
7838                                    + cpr.appInfo.packageName + ": " + e);
7839                        }
7840
7841                        // Use existing process if already started
7842                        ProcessRecord proc = getProcessRecordLocked(
7843                                cpi.processName, cpr.appInfo.uid, false);
7844                        if (proc != null && proc.thread != null) {
7845                            if (DEBUG_PROVIDER) {
7846                                Slog.d(TAG, "Installing in existing process " + proc);
7847                            }
7848                            proc.pubProviders.put(cpi.name, cpr);
7849                            try {
7850                                proc.thread.scheduleInstallProvider(cpi);
7851                            } catch (RemoteException e) {
7852                            }
7853                        } else {
7854                            proc = startProcessLocked(cpi.processName,
7855                                    cpr.appInfo, false, 0, "content provider",
7856                                    new ComponentName(cpi.applicationInfo.packageName,
7857                                            cpi.name), false, false, false);
7858                            if (proc == null) {
7859                                Slog.w(TAG, "Unable to launch app "
7860                                        + cpi.applicationInfo.packageName + "/"
7861                                        + cpi.applicationInfo.uid + " for provider "
7862                                        + name + ": process is bad");
7863                                return null;
7864                            }
7865                        }
7866                        cpr.launchingApp = proc;
7867                        mLaunchingProviders.add(cpr);
7868                    } finally {
7869                        Binder.restoreCallingIdentity(origId);
7870                    }
7871                }
7872
7873                // Make sure the provider is published (the same provider class
7874                // may be published under multiple names).
7875                if (firstClass) {
7876                    mProviderMap.putProviderByClass(comp, cpr);
7877                }
7878
7879                mProviderMap.putProviderByName(name, cpr);
7880                conn = incProviderCountLocked(r, cpr, token, stable);
7881                if (conn != null) {
7882                    conn.waiting = true;
7883                }
7884            }
7885        }
7886
7887        // Wait for the provider to be published...
7888        synchronized (cpr) {
7889            while (cpr.provider == null) {
7890                if (cpr.launchingApp == null) {
7891                    Slog.w(TAG, "Unable to launch app "
7892                            + cpi.applicationInfo.packageName + "/"
7893                            + cpi.applicationInfo.uid + " for provider "
7894                            + name + ": launching app became null");
7895                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7896                            UserHandle.getUserId(cpi.applicationInfo.uid),
7897                            cpi.applicationInfo.packageName,
7898                            cpi.applicationInfo.uid, name);
7899                    return null;
7900                }
7901                try {
7902                    if (DEBUG_MU) {
7903                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7904                                + cpr.launchingApp);
7905                    }
7906                    if (conn != null) {
7907                        conn.waiting = true;
7908                    }
7909                    cpr.wait();
7910                } catch (InterruptedException ex) {
7911                } finally {
7912                    if (conn != null) {
7913                        conn.waiting = false;
7914                    }
7915                }
7916            }
7917        }
7918        return cpr != null ? cpr.newHolder(conn) : null;
7919    }
7920
7921    public final ContentProviderHolder getContentProvider(
7922            IApplicationThread caller, String name, int userId, boolean stable) {
7923        enforceNotIsolatedCaller("getContentProvider");
7924        if (caller == null) {
7925            String msg = "null IApplicationThread when getting content provider "
7926                    + name;
7927            Slog.w(TAG, msg);
7928            throw new SecurityException(msg);
7929        }
7930
7931        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7932                false, true, "getContentProvider", null);
7933        return getContentProviderImpl(caller, name, null, stable, userId);
7934    }
7935
7936    public ContentProviderHolder getContentProviderExternal(
7937            String name, int userId, IBinder token) {
7938        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7939            "Do not have permission in call getContentProviderExternal()");
7940        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7941                false, true, "getContentProvider", null);
7942        return getContentProviderExternalUnchecked(name, token, userId);
7943    }
7944
7945    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7946            IBinder token, int userId) {
7947        return getContentProviderImpl(null, name, token, true, userId);
7948    }
7949
7950    /**
7951     * Drop a content provider from a ProcessRecord's bookkeeping
7952     */
7953    public void removeContentProvider(IBinder connection, boolean stable) {
7954        enforceNotIsolatedCaller("removeContentProvider");
7955        long ident = Binder.clearCallingIdentity();
7956        try {
7957            synchronized (this) {
7958                ContentProviderConnection conn;
7959                try {
7960                    conn = (ContentProviderConnection)connection;
7961                } catch (ClassCastException e) {
7962                    String msg ="removeContentProvider: " + connection
7963                            + " not a ContentProviderConnection";
7964                    Slog.w(TAG, msg);
7965                    throw new IllegalArgumentException(msg);
7966                }
7967                if (conn == null) {
7968                    throw new NullPointerException("connection is null");
7969                }
7970                if (decProviderCountLocked(conn, null, null, stable)) {
7971                    updateOomAdjLocked();
7972                }
7973            }
7974        } finally {
7975            Binder.restoreCallingIdentity(ident);
7976        }
7977    }
7978
7979    public void removeContentProviderExternal(String name, IBinder token) {
7980        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7981            "Do not have permission in call removeContentProviderExternal()");
7982        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7983    }
7984
7985    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7986        synchronized (this) {
7987            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7988            if(cpr == null) {
7989                //remove from mProvidersByClass
7990                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7991                return;
7992            }
7993
7994            //update content provider record entry info
7995            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7996            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7997            if (localCpr.hasExternalProcessHandles()) {
7998                if (localCpr.removeExternalProcessHandleLocked(token)) {
7999                    updateOomAdjLocked();
8000                } else {
8001                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8002                            + " with no external reference for token: "
8003                            + token + ".");
8004                }
8005            } else {
8006                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8007                        + " with no external references.");
8008            }
8009        }
8010    }
8011
8012    public final void publishContentProviders(IApplicationThread caller,
8013            List<ContentProviderHolder> providers) {
8014        if (providers == null) {
8015            return;
8016        }
8017
8018        enforceNotIsolatedCaller("publishContentProviders");
8019        synchronized (this) {
8020            final ProcessRecord r = getRecordForAppLocked(caller);
8021            if (DEBUG_MU)
8022                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8023            if (r == null) {
8024                throw new SecurityException(
8025                        "Unable to find app for caller " + caller
8026                      + " (pid=" + Binder.getCallingPid()
8027                      + ") when publishing content providers");
8028            }
8029
8030            final long origId = Binder.clearCallingIdentity();
8031
8032            final int N = providers.size();
8033            for (int i=0; i<N; i++) {
8034                ContentProviderHolder src = providers.get(i);
8035                if (src == null || src.info == null || src.provider == null) {
8036                    continue;
8037                }
8038                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8039                if (DEBUG_MU)
8040                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8041                if (dst != null) {
8042                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8043                    mProviderMap.putProviderByClass(comp, dst);
8044                    String names[] = dst.info.authority.split(";");
8045                    for (int j = 0; j < names.length; j++) {
8046                        mProviderMap.putProviderByName(names[j], dst);
8047                    }
8048
8049                    int NL = mLaunchingProviders.size();
8050                    int j;
8051                    for (j=0; j<NL; j++) {
8052                        if (mLaunchingProviders.get(j) == dst) {
8053                            mLaunchingProviders.remove(j);
8054                            j--;
8055                            NL--;
8056                        }
8057                    }
8058                    synchronized (dst) {
8059                        dst.provider = src.provider;
8060                        dst.proc = r;
8061                        dst.notifyAll();
8062                    }
8063                    updateOomAdjLocked(r);
8064                }
8065            }
8066
8067            Binder.restoreCallingIdentity(origId);
8068        }
8069    }
8070
8071    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8072        ContentProviderConnection conn;
8073        try {
8074            conn = (ContentProviderConnection)connection;
8075        } catch (ClassCastException e) {
8076            String msg ="refContentProvider: " + connection
8077                    + " not a ContentProviderConnection";
8078            Slog.w(TAG, msg);
8079            throw new IllegalArgumentException(msg);
8080        }
8081        if (conn == null) {
8082            throw new NullPointerException("connection is null");
8083        }
8084
8085        synchronized (this) {
8086            if (stable > 0) {
8087                conn.numStableIncs += stable;
8088            }
8089            stable = conn.stableCount + stable;
8090            if (stable < 0) {
8091                throw new IllegalStateException("stableCount < 0: " + stable);
8092            }
8093
8094            if (unstable > 0) {
8095                conn.numUnstableIncs += unstable;
8096            }
8097            unstable = conn.unstableCount + unstable;
8098            if (unstable < 0) {
8099                throw new IllegalStateException("unstableCount < 0: " + unstable);
8100            }
8101
8102            if ((stable+unstable) <= 0) {
8103                throw new IllegalStateException("ref counts can't go to zero here: stable="
8104                        + stable + " unstable=" + unstable);
8105            }
8106            conn.stableCount = stable;
8107            conn.unstableCount = unstable;
8108            return !conn.dead;
8109        }
8110    }
8111
8112    public void unstableProviderDied(IBinder connection) {
8113        ContentProviderConnection conn;
8114        try {
8115            conn = (ContentProviderConnection)connection;
8116        } catch (ClassCastException e) {
8117            String msg ="refContentProvider: " + connection
8118                    + " not a ContentProviderConnection";
8119            Slog.w(TAG, msg);
8120            throw new IllegalArgumentException(msg);
8121        }
8122        if (conn == null) {
8123            throw new NullPointerException("connection is null");
8124        }
8125
8126        // Safely retrieve the content provider associated with the connection.
8127        IContentProvider provider;
8128        synchronized (this) {
8129            provider = conn.provider.provider;
8130        }
8131
8132        if (provider == null) {
8133            // Um, yeah, we're way ahead of you.
8134            return;
8135        }
8136
8137        // Make sure the caller is being honest with us.
8138        if (provider.asBinder().pingBinder()) {
8139            // Er, no, still looks good to us.
8140            synchronized (this) {
8141                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8142                        + " says " + conn + " died, but we don't agree");
8143                return;
8144            }
8145        }
8146
8147        // Well look at that!  It's dead!
8148        synchronized (this) {
8149            if (conn.provider.provider != provider) {
8150                // But something changed...  good enough.
8151                return;
8152            }
8153
8154            ProcessRecord proc = conn.provider.proc;
8155            if (proc == null || proc.thread == null) {
8156                // Seems like the process is already cleaned up.
8157                return;
8158            }
8159
8160            // As far as we're concerned, this is just like receiving a
8161            // death notification...  just a bit prematurely.
8162            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8163                    + ") early provider death");
8164            final long ident = Binder.clearCallingIdentity();
8165            try {
8166                appDiedLocked(proc, proc.pid, proc.thread);
8167            } finally {
8168                Binder.restoreCallingIdentity(ident);
8169            }
8170        }
8171    }
8172
8173    @Override
8174    public void appNotRespondingViaProvider(IBinder connection) {
8175        enforceCallingPermission(
8176                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8177
8178        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8179        if (conn == null) {
8180            Slog.w(TAG, "ContentProviderConnection is null");
8181            return;
8182        }
8183
8184        final ProcessRecord host = conn.provider.proc;
8185        if (host == null) {
8186            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8187            return;
8188        }
8189
8190        final long token = Binder.clearCallingIdentity();
8191        try {
8192            appNotResponding(host, null, null, false, "ContentProvider not responding");
8193        } finally {
8194            Binder.restoreCallingIdentity(token);
8195        }
8196    }
8197
8198    public final void installSystemProviders() {
8199        List<ProviderInfo> providers;
8200        synchronized (this) {
8201            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8202            providers = generateApplicationProvidersLocked(app);
8203            if (providers != null) {
8204                for (int i=providers.size()-1; i>=0; i--) {
8205                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8206                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8207                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8208                                + ": not system .apk");
8209                        providers.remove(i);
8210                    }
8211                }
8212            }
8213        }
8214        if (providers != null) {
8215            mSystemThread.installSystemProviders(providers);
8216        }
8217
8218        mCoreSettingsObserver = new CoreSettingsObserver(this);
8219
8220        mUsageStatsService.monitorPackages();
8221    }
8222
8223    /**
8224     * Allows app to retrieve the MIME type of a URI without having permission
8225     * to access its content provider.
8226     *
8227     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8228     *
8229     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8230     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8231     */
8232    public String getProviderMimeType(Uri uri, int userId) {
8233        enforceNotIsolatedCaller("getProviderMimeType");
8234        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8235                userId, false, true, "getProviderMimeType", null);
8236        final String name = uri.getAuthority();
8237        final long ident = Binder.clearCallingIdentity();
8238        ContentProviderHolder holder = null;
8239
8240        try {
8241            holder = getContentProviderExternalUnchecked(name, null, userId);
8242            if (holder != null) {
8243                return holder.provider.getType(uri);
8244            }
8245        } catch (RemoteException e) {
8246            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8247            return null;
8248        } finally {
8249            if (holder != null) {
8250                removeContentProviderExternalUnchecked(name, null, userId);
8251            }
8252            Binder.restoreCallingIdentity(ident);
8253        }
8254
8255        return null;
8256    }
8257
8258    // =========================================================
8259    // GLOBAL MANAGEMENT
8260    // =========================================================
8261
8262    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8263            boolean isolated) {
8264        String proc = customProcess != null ? customProcess : info.processName;
8265        BatteryStatsImpl.Uid.Proc ps = null;
8266        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8267        int uid = info.uid;
8268        if (isolated) {
8269            int userId = UserHandle.getUserId(uid);
8270            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8271            while (true) {
8272                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8273                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8274                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8275                }
8276                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8277                mNextIsolatedProcessUid++;
8278                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8279                    // No process for this uid, use it.
8280                    break;
8281                }
8282                stepsLeft--;
8283                if (stepsLeft <= 0) {
8284                    return null;
8285                }
8286            }
8287        }
8288        return new ProcessRecord(stats, info, proc, uid);
8289    }
8290
8291    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8292        ProcessRecord app;
8293        if (!isolated) {
8294            app = getProcessRecordLocked(info.processName, info.uid, true);
8295        } else {
8296            app = null;
8297        }
8298
8299        if (app == null) {
8300            app = newProcessRecordLocked(info, null, isolated);
8301            mProcessNames.put(info.processName, app.uid, app);
8302            if (isolated) {
8303                mIsolatedProcesses.put(app.uid, app);
8304            }
8305            updateLruProcessLocked(app, false, null);
8306            updateOomAdjLocked();
8307        }
8308
8309        // This package really, really can not be stopped.
8310        try {
8311            AppGlobals.getPackageManager().setPackageStoppedState(
8312                    info.packageName, false, UserHandle.getUserId(app.uid));
8313        } catch (RemoteException e) {
8314        } catch (IllegalArgumentException e) {
8315            Slog.w(TAG, "Failed trying to unstop package "
8316                    + info.packageName + ": " + e);
8317        }
8318
8319        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8320                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8321            app.persistent = true;
8322            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8323        }
8324        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8325            mPersistentStartingProcesses.add(app);
8326            startProcessLocked(app, "added application", app.processName);
8327        }
8328
8329        return app;
8330    }
8331
8332    public void unhandledBack() {
8333        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8334                "unhandledBack()");
8335
8336        synchronized(this) {
8337            final long origId = Binder.clearCallingIdentity();
8338            try {
8339                getFocusedStack().unhandledBackLocked();
8340            } finally {
8341                Binder.restoreCallingIdentity(origId);
8342            }
8343        }
8344    }
8345
8346    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8347        enforceNotIsolatedCaller("openContentUri");
8348        final int userId = UserHandle.getCallingUserId();
8349        String name = uri.getAuthority();
8350        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8351        ParcelFileDescriptor pfd = null;
8352        if (cph != null) {
8353            // We record the binder invoker's uid in thread-local storage before
8354            // going to the content provider to open the file.  Later, in the code
8355            // that handles all permissions checks, we look for this uid and use
8356            // that rather than the Activity Manager's own uid.  The effect is that
8357            // we do the check against the caller's permissions even though it looks
8358            // to the content provider like the Activity Manager itself is making
8359            // the request.
8360            sCallerIdentity.set(new Identity(
8361                    Binder.getCallingPid(), Binder.getCallingUid()));
8362            try {
8363                pfd = cph.provider.openFile(null, uri, "r", null);
8364            } catch (FileNotFoundException e) {
8365                // do nothing; pfd will be returned null
8366            } finally {
8367                // Ensure that whatever happens, we clean up the identity state
8368                sCallerIdentity.remove();
8369            }
8370
8371            // We've got the fd now, so we're done with the provider.
8372            removeContentProviderExternalUnchecked(name, null, userId);
8373        } else {
8374            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8375        }
8376        return pfd;
8377    }
8378
8379    // Actually is sleeping or shutting down or whatever else in the future
8380    // is an inactive state.
8381    public boolean isSleepingOrShuttingDown() {
8382        return mSleeping || mShuttingDown;
8383    }
8384
8385    public void goingToSleep() {
8386        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8387                != PackageManager.PERMISSION_GRANTED) {
8388            throw new SecurityException("Requires permission "
8389                    + android.Manifest.permission.DEVICE_POWER);
8390        }
8391
8392        synchronized(this) {
8393            mWentToSleep = true;
8394            updateEventDispatchingLocked();
8395
8396            if (!mSleeping) {
8397                mSleeping = true;
8398                mStackSupervisor.goingToSleepLocked();
8399
8400                // Initialize the wake times of all processes.
8401                checkExcessivePowerUsageLocked(false);
8402                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8403                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8404                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8405            }
8406        }
8407    }
8408
8409    @Override
8410    public boolean shutdown(int timeout) {
8411        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8412                != PackageManager.PERMISSION_GRANTED) {
8413            throw new SecurityException("Requires permission "
8414                    + android.Manifest.permission.SHUTDOWN);
8415        }
8416
8417        boolean timedout = false;
8418
8419        synchronized(this) {
8420            mShuttingDown = true;
8421            updateEventDispatchingLocked();
8422            timedout = mStackSupervisor.shutdownLocked(timeout);
8423        }
8424
8425        mAppOpsService.shutdown();
8426        mUsageStatsService.shutdown();
8427        mBatteryStatsService.shutdown();
8428        synchronized (this) {
8429            mProcessStats.shutdownLocked();
8430        }
8431
8432        return timedout;
8433    }
8434
8435    public final void activitySlept(IBinder token) {
8436        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8437
8438        final long origId = Binder.clearCallingIdentity();
8439
8440        synchronized (this) {
8441            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8442            if (r != null) {
8443                mStackSupervisor.activitySleptLocked(r);
8444            }
8445        }
8446
8447        Binder.restoreCallingIdentity(origId);
8448    }
8449
8450    void logLockScreen(String msg) {
8451        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8452                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8453                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8454                mStackSupervisor.mDismissKeyguardOnNextActivity);
8455    }
8456
8457    private void comeOutOfSleepIfNeededLocked() {
8458        if (!mWentToSleep && !mLockScreenShown) {
8459            if (mSleeping) {
8460                mSleeping = false;
8461                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8462            }
8463        }
8464    }
8465
8466    public void wakingUp() {
8467        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8468                != PackageManager.PERMISSION_GRANTED) {
8469            throw new SecurityException("Requires permission "
8470                    + android.Manifest.permission.DEVICE_POWER);
8471        }
8472
8473        synchronized(this) {
8474            mWentToSleep = false;
8475            updateEventDispatchingLocked();
8476            comeOutOfSleepIfNeededLocked();
8477        }
8478    }
8479
8480    private void updateEventDispatchingLocked() {
8481        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8482    }
8483
8484    public void setLockScreenShown(boolean shown) {
8485        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8486                != PackageManager.PERMISSION_GRANTED) {
8487            throw new SecurityException("Requires permission "
8488                    + android.Manifest.permission.DEVICE_POWER);
8489        }
8490
8491        synchronized(this) {
8492            long ident = Binder.clearCallingIdentity();
8493            try {
8494                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8495                mLockScreenShown = shown;
8496                comeOutOfSleepIfNeededLocked();
8497            } finally {
8498                Binder.restoreCallingIdentity(ident);
8499            }
8500        }
8501    }
8502
8503    public void stopAppSwitches() {
8504        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8505                != PackageManager.PERMISSION_GRANTED) {
8506            throw new SecurityException("Requires permission "
8507                    + android.Manifest.permission.STOP_APP_SWITCHES);
8508        }
8509
8510        synchronized(this) {
8511            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8512                    + APP_SWITCH_DELAY_TIME;
8513            mDidAppSwitch = false;
8514            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8515            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8516            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8517        }
8518    }
8519
8520    public void resumeAppSwitches() {
8521        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8522                != PackageManager.PERMISSION_GRANTED) {
8523            throw new SecurityException("Requires permission "
8524                    + android.Manifest.permission.STOP_APP_SWITCHES);
8525        }
8526
8527        synchronized(this) {
8528            // Note that we don't execute any pending app switches... we will
8529            // let those wait until either the timeout, or the next start
8530            // activity request.
8531            mAppSwitchesAllowedTime = 0;
8532        }
8533    }
8534
8535    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8536            String name) {
8537        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8538            return true;
8539        }
8540
8541        final int perm = checkComponentPermission(
8542                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8543                callingUid, -1, true);
8544        if (perm == PackageManager.PERMISSION_GRANTED) {
8545            return true;
8546        }
8547
8548        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8549        return false;
8550    }
8551
8552    public void setDebugApp(String packageName, boolean waitForDebugger,
8553            boolean persistent) {
8554        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8555                "setDebugApp()");
8556
8557        long ident = Binder.clearCallingIdentity();
8558        try {
8559            // Note that this is not really thread safe if there are multiple
8560            // callers into it at the same time, but that's not a situation we
8561            // care about.
8562            if (persistent) {
8563                final ContentResolver resolver = mContext.getContentResolver();
8564                Settings.Global.putString(
8565                    resolver, Settings.Global.DEBUG_APP,
8566                    packageName);
8567                Settings.Global.putInt(
8568                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8569                    waitForDebugger ? 1 : 0);
8570            }
8571
8572            synchronized (this) {
8573                if (!persistent) {
8574                    mOrigDebugApp = mDebugApp;
8575                    mOrigWaitForDebugger = mWaitForDebugger;
8576                }
8577                mDebugApp = packageName;
8578                mWaitForDebugger = waitForDebugger;
8579                mDebugTransient = !persistent;
8580                if (packageName != null) {
8581                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8582                            false, UserHandle.USER_ALL, "set debug app");
8583                }
8584            }
8585        } finally {
8586            Binder.restoreCallingIdentity(ident);
8587        }
8588    }
8589
8590    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8591        synchronized (this) {
8592            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8593            if (!isDebuggable) {
8594                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8595                    throw new SecurityException("Process not debuggable: " + app.packageName);
8596                }
8597            }
8598
8599            mOpenGlTraceApp = processName;
8600        }
8601    }
8602
8603    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8604            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8605        synchronized (this) {
8606            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8607            if (!isDebuggable) {
8608                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8609                    throw new SecurityException("Process not debuggable: " + app.packageName);
8610                }
8611            }
8612            mProfileApp = processName;
8613            mProfileFile = profileFile;
8614            if (mProfileFd != null) {
8615                try {
8616                    mProfileFd.close();
8617                } catch (IOException e) {
8618                }
8619                mProfileFd = null;
8620            }
8621            mProfileFd = profileFd;
8622            mProfileType = 0;
8623            mAutoStopProfiler = autoStopProfiler;
8624        }
8625    }
8626
8627    @Override
8628    public void setAlwaysFinish(boolean enabled) {
8629        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8630                "setAlwaysFinish()");
8631
8632        Settings.Global.putInt(
8633                mContext.getContentResolver(),
8634                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8635
8636        synchronized (this) {
8637            mAlwaysFinishActivities = enabled;
8638        }
8639    }
8640
8641    @Override
8642    public void setActivityController(IActivityController controller) {
8643        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8644                "setActivityController()");
8645        synchronized (this) {
8646            mController = controller;
8647            Watchdog.getInstance().setActivityController(controller);
8648        }
8649    }
8650
8651    @Override
8652    public void setUserIsMonkey(boolean userIsMonkey) {
8653        synchronized (this) {
8654            synchronized (mPidsSelfLocked) {
8655                final int callingPid = Binder.getCallingPid();
8656                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8657                if (precessRecord == null) {
8658                    throw new SecurityException("Unknown process: " + callingPid);
8659                }
8660                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8661                    throw new SecurityException("Only an instrumentation process "
8662                            + "with a UiAutomation can call setUserIsMonkey");
8663                }
8664            }
8665            mUserIsMonkey = userIsMonkey;
8666        }
8667    }
8668
8669    @Override
8670    public boolean isUserAMonkey() {
8671        synchronized (this) {
8672            // If there is a controller also implies the user is a monkey.
8673            return (mUserIsMonkey || mController != null);
8674        }
8675    }
8676
8677    public void requestBugReport() {
8678        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8679        SystemProperties.set("ctl.start", "bugreport");
8680    }
8681
8682    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8683        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8684    }
8685
8686    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8687        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8688            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8689        }
8690        return KEY_DISPATCHING_TIMEOUT;
8691    }
8692
8693    @Override
8694    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8695        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8696                != PackageManager.PERMISSION_GRANTED) {
8697            throw new SecurityException("Requires permission "
8698                    + android.Manifest.permission.FILTER_EVENTS);
8699        }
8700        ProcessRecord proc;
8701        long timeout;
8702        synchronized (this) {
8703            synchronized (mPidsSelfLocked) {
8704                proc = mPidsSelfLocked.get(pid);
8705            }
8706            timeout = getInputDispatchingTimeoutLocked(proc);
8707        }
8708
8709        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8710            return -1;
8711        }
8712
8713        return timeout;
8714    }
8715
8716    /**
8717     * Handle input dispatching timeouts.
8718     * Returns whether input dispatching should be aborted or not.
8719     */
8720    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8721            final ActivityRecord activity, final ActivityRecord parent,
8722            final boolean aboveSystem, String reason) {
8723        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8724                != PackageManager.PERMISSION_GRANTED) {
8725            throw new SecurityException("Requires permission "
8726                    + android.Manifest.permission.FILTER_EVENTS);
8727        }
8728
8729        final String annotation;
8730        if (reason == null) {
8731            annotation = "Input dispatching timed out";
8732        } else {
8733            annotation = "Input dispatching timed out (" + reason + ")";
8734        }
8735
8736        if (proc != null) {
8737            synchronized (this) {
8738                if (proc.debugging) {
8739                    return false;
8740                }
8741
8742                if (mDidDexOpt) {
8743                    // Give more time since we were dexopting.
8744                    mDidDexOpt = false;
8745                    return false;
8746                }
8747
8748                if (proc.instrumentationClass != null) {
8749                    Bundle info = new Bundle();
8750                    info.putString("shortMsg", "keyDispatchingTimedOut");
8751                    info.putString("longMsg", annotation);
8752                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8753                    return true;
8754                }
8755            }
8756            mHandler.post(new Runnable() {
8757                @Override
8758                public void run() {
8759                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8760                }
8761            });
8762        }
8763
8764        return true;
8765    }
8766
8767    public Bundle getAssistContextExtras(int requestType) {
8768        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8769                "getAssistContextExtras()");
8770        PendingAssistExtras pae;
8771        Bundle extras = new Bundle();
8772        synchronized (this) {
8773            ActivityRecord activity = getFocusedStack().mResumedActivity;
8774            if (activity == null) {
8775                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8776                return null;
8777            }
8778            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8779            if (activity.app == null || activity.app.thread == null) {
8780                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8781                return extras;
8782            }
8783            if (activity.app.pid == Binder.getCallingPid()) {
8784                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8785                return extras;
8786            }
8787            pae = new PendingAssistExtras(activity);
8788            try {
8789                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8790                        requestType);
8791                mPendingAssistExtras.add(pae);
8792                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8793            } catch (RemoteException e) {
8794                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8795                return extras;
8796            }
8797        }
8798        synchronized (pae) {
8799            while (!pae.haveResult) {
8800                try {
8801                    pae.wait();
8802                } catch (InterruptedException e) {
8803                }
8804            }
8805            if (pae.result != null) {
8806                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8807            }
8808        }
8809        synchronized (this) {
8810            mPendingAssistExtras.remove(pae);
8811            mHandler.removeCallbacks(pae);
8812        }
8813        return extras;
8814    }
8815
8816    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8817        PendingAssistExtras pae = (PendingAssistExtras)token;
8818        synchronized (pae) {
8819            pae.result = extras;
8820            pae.haveResult = true;
8821            pae.notifyAll();
8822        }
8823    }
8824
8825    public void registerProcessObserver(IProcessObserver observer) {
8826        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8827                "registerProcessObserver()");
8828        synchronized (this) {
8829            mProcessObservers.register(observer);
8830        }
8831    }
8832
8833    @Override
8834    public void unregisterProcessObserver(IProcessObserver observer) {
8835        synchronized (this) {
8836            mProcessObservers.unregister(observer);
8837        }
8838    }
8839
8840    @Override
8841    public boolean convertFromTranslucent(IBinder token) {
8842        final long origId = Binder.clearCallingIdentity();
8843        try {
8844            synchronized (this) {
8845                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8846                if (r == null) {
8847                    return false;
8848                }
8849                if (r.changeWindowTranslucency(true)) {
8850                    mWindowManager.setAppFullscreen(token, true);
8851                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8852                    return true;
8853                }
8854                return false;
8855            }
8856        } finally {
8857            Binder.restoreCallingIdentity(origId);
8858        }
8859    }
8860
8861    @Override
8862    public boolean convertToTranslucent(IBinder token) {
8863        final long origId = Binder.clearCallingIdentity();
8864        try {
8865            synchronized (this) {
8866                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8867                if (r == null) {
8868                    return false;
8869                }
8870                if (r.changeWindowTranslucency(false)) {
8871                    r.task.stack.convertToTranslucent(r);
8872                    mWindowManager.setAppFullscreen(token, false);
8873                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8874                    return true;
8875                }
8876                return false;
8877            }
8878        } finally {
8879            Binder.restoreCallingIdentity(origId);
8880        }
8881    }
8882
8883    @Override
8884    public void setImmersive(IBinder token, boolean immersive) {
8885        synchronized(this) {
8886            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8887            if (r == null) {
8888                throw new IllegalArgumentException();
8889            }
8890            r.immersive = immersive;
8891
8892            // update associated state if we're frontmost
8893            if (r == mFocusedActivity) {
8894                if (DEBUG_IMMERSIVE) {
8895                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8896                }
8897                applyUpdateLockStateLocked(r);
8898            }
8899        }
8900    }
8901
8902    @Override
8903    public boolean isImmersive(IBinder token) {
8904        synchronized (this) {
8905            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8906            if (r == null) {
8907                throw new IllegalArgumentException();
8908            }
8909            return r.immersive;
8910        }
8911    }
8912
8913    public boolean isTopActivityImmersive() {
8914        enforceNotIsolatedCaller("startActivity");
8915        synchronized (this) {
8916            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8917            return (r != null) ? r.immersive : false;
8918        }
8919    }
8920
8921    public final void enterSafeMode() {
8922        synchronized(this) {
8923            // It only makes sense to do this before the system is ready
8924            // and started launching other packages.
8925            if (!mSystemReady) {
8926                try {
8927                    AppGlobals.getPackageManager().enterSafeMode();
8928                } catch (RemoteException e) {
8929                }
8930            }
8931        }
8932    }
8933
8934    public final void showSafeModeOverlay() {
8935        View v = LayoutInflater.from(mContext).inflate(
8936                com.android.internal.R.layout.safe_mode, null);
8937        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8938        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8939        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8940        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8941        lp.gravity = Gravity.BOTTOM | Gravity.START;
8942        lp.format = v.getBackground().getOpacity();
8943        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8944                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8945        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8946        ((WindowManager)mContext.getSystemService(
8947                Context.WINDOW_SERVICE)).addView(v, lp);
8948    }
8949
8950    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8951        if (!(sender instanceof PendingIntentRecord)) {
8952            return;
8953        }
8954        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8955        synchronized (stats) {
8956            if (mBatteryStatsService.isOnBattery()) {
8957                mBatteryStatsService.enforceCallingPermission();
8958                PendingIntentRecord rec = (PendingIntentRecord)sender;
8959                int MY_UID = Binder.getCallingUid();
8960                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8961                BatteryStatsImpl.Uid.Pkg pkg =
8962                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8963                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8964                pkg.incWakeupsLocked();
8965            }
8966        }
8967    }
8968
8969    public boolean killPids(int[] pids, String pReason, boolean secure) {
8970        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8971            throw new SecurityException("killPids only available to the system");
8972        }
8973        String reason = (pReason == null) ? "Unknown" : pReason;
8974        // XXX Note: don't acquire main activity lock here, because the window
8975        // manager calls in with its locks held.
8976
8977        boolean killed = false;
8978        synchronized (mPidsSelfLocked) {
8979            int[] types = new int[pids.length];
8980            int worstType = 0;
8981            for (int i=0; i<pids.length; i++) {
8982                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8983                if (proc != null) {
8984                    int type = proc.setAdj;
8985                    types[i] = type;
8986                    if (type > worstType) {
8987                        worstType = type;
8988                    }
8989                }
8990            }
8991
8992            // If the worst oom_adj is somewhere in the cached proc LRU range,
8993            // then constrain it so we will kill all cached procs.
8994            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8995                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8996                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8997            }
8998
8999            // If this is not a secure call, don't let it kill processes that
9000            // are important.
9001            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9002                worstType = ProcessList.SERVICE_ADJ;
9003            }
9004
9005            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9006            for (int i=0; i<pids.length; i++) {
9007                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9008                if (proc == null) {
9009                    continue;
9010                }
9011                int adj = proc.setAdj;
9012                if (adj >= worstType && !proc.killedByAm) {
9013                    killUnneededProcessLocked(proc, reason);
9014                    killed = true;
9015                }
9016            }
9017        }
9018        return killed;
9019    }
9020
9021    @Override
9022    public void killUid(int uid, String reason) {
9023        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9024            throw new SecurityException("killUid only available to the system");
9025        }
9026        synchronized (this) {
9027            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9028                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9029                    reason != null ? reason : "kill uid");
9030        }
9031    }
9032
9033    @Override
9034    public boolean killProcessesBelowForeground(String reason) {
9035        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9036            throw new SecurityException("killProcessesBelowForeground() only available to system");
9037        }
9038
9039        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9040    }
9041
9042    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9043        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9044            throw new SecurityException("killProcessesBelowAdj() only available to system");
9045        }
9046
9047        boolean killed = false;
9048        synchronized (mPidsSelfLocked) {
9049            final int size = mPidsSelfLocked.size();
9050            for (int i = 0; i < size; i++) {
9051                final int pid = mPidsSelfLocked.keyAt(i);
9052                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9053                if (proc == null) continue;
9054
9055                final int adj = proc.setAdj;
9056                if (adj > belowAdj && !proc.killedByAm) {
9057                    killUnneededProcessLocked(proc, reason);
9058                    killed = true;
9059                }
9060            }
9061        }
9062        return killed;
9063    }
9064
9065    @Override
9066    public void hang(final IBinder who, boolean allowRestart) {
9067        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9068                != PackageManager.PERMISSION_GRANTED) {
9069            throw new SecurityException("Requires permission "
9070                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9071        }
9072
9073        final IBinder.DeathRecipient death = new DeathRecipient() {
9074            @Override
9075            public void binderDied() {
9076                synchronized (this) {
9077                    notifyAll();
9078                }
9079            }
9080        };
9081
9082        try {
9083            who.linkToDeath(death, 0);
9084        } catch (RemoteException e) {
9085            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9086            return;
9087        }
9088
9089        synchronized (this) {
9090            Watchdog.getInstance().setAllowRestart(allowRestart);
9091            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9092            synchronized (death) {
9093                while (who.isBinderAlive()) {
9094                    try {
9095                        death.wait();
9096                    } catch (InterruptedException e) {
9097                    }
9098                }
9099            }
9100            Watchdog.getInstance().setAllowRestart(true);
9101        }
9102    }
9103
9104    @Override
9105    public void restart() {
9106        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9107                != PackageManager.PERMISSION_GRANTED) {
9108            throw new SecurityException("Requires permission "
9109                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9110        }
9111
9112        Log.i(TAG, "Sending shutdown broadcast...");
9113
9114        BroadcastReceiver br = new BroadcastReceiver() {
9115            @Override public void onReceive(Context context, Intent intent) {
9116                // Now the broadcast is done, finish up the low-level shutdown.
9117                Log.i(TAG, "Shutting down activity manager...");
9118                shutdown(10000);
9119                Log.i(TAG, "Shutdown complete, restarting!");
9120                Process.killProcess(Process.myPid());
9121                System.exit(10);
9122            }
9123        };
9124
9125        // First send the high-level shut down broadcast.
9126        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9127        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9128        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9129        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9130        mContext.sendOrderedBroadcastAsUser(intent,
9131                UserHandle.ALL, null, br, mHandler, 0, null, null);
9132        */
9133        br.onReceive(mContext, intent);
9134    }
9135
9136    private long getLowRamTimeSinceIdle(long now) {
9137        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9138    }
9139
9140    @Override
9141    public void performIdleMaintenance() {
9142        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9143                != PackageManager.PERMISSION_GRANTED) {
9144            throw new SecurityException("Requires permission "
9145                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9146        }
9147
9148        synchronized (this) {
9149            final long now = SystemClock.uptimeMillis();
9150            final long timeSinceLastIdle = now - mLastIdleTime;
9151            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9152            mLastIdleTime = now;
9153            mLowRamTimeSinceLastIdle = 0;
9154            if (mLowRamStartTime != 0) {
9155                mLowRamStartTime = now;
9156            }
9157
9158            StringBuilder sb = new StringBuilder(128);
9159            sb.append("Idle maintenance over ");
9160            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9161            sb.append(" low RAM for ");
9162            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9163            Slog.i(TAG, sb.toString());
9164
9165            // If at least 1/3 of our time since the last idle period has been spent
9166            // with RAM low, then we want to kill processes.
9167            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9168
9169            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9170                ProcessRecord proc = mLruProcesses.get(i);
9171                if (proc.notCachedSinceIdle) {
9172                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9173                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9174                        if (doKilling && proc.initialIdlePss != 0
9175                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9176                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9177                                    + " from " + proc.initialIdlePss + ")");
9178                        }
9179                    }
9180                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9181                    proc.notCachedSinceIdle = true;
9182                    proc.initialIdlePss = 0;
9183                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9184                            mSleeping, now);
9185                }
9186            }
9187
9188            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9189            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9190        }
9191    }
9192
9193    public final void startRunning(String pkg, String cls, String action,
9194            String data) {
9195        synchronized(this) {
9196            if (mStartRunning) {
9197                return;
9198            }
9199            mStartRunning = true;
9200            mTopComponent = pkg != null && cls != null
9201                    ? new ComponentName(pkg, cls) : null;
9202            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9203            mTopData = data;
9204            if (!mSystemReady) {
9205                return;
9206            }
9207        }
9208
9209        systemReady(null);
9210    }
9211
9212    private void retrieveSettings() {
9213        final ContentResolver resolver = mContext.getContentResolver();
9214        String debugApp = Settings.Global.getString(
9215            resolver, Settings.Global.DEBUG_APP);
9216        boolean waitForDebugger = Settings.Global.getInt(
9217            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9218        boolean alwaysFinishActivities = Settings.Global.getInt(
9219            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9220        boolean forceRtl = Settings.Global.getInt(
9221                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9222        // Transfer any global setting for forcing RTL layout, into a System Property
9223        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9224
9225        Configuration configuration = new Configuration();
9226        Settings.System.getConfiguration(resolver, configuration);
9227        if (forceRtl) {
9228            // This will take care of setting the correct layout direction flags
9229            configuration.setLayoutDirection(configuration.locale);
9230        }
9231
9232        synchronized (this) {
9233            mDebugApp = mOrigDebugApp = debugApp;
9234            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9235            mAlwaysFinishActivities = alwaysFinishActivities;
9236            // This happens before any activities are started, so we can
9237            // change mConfiguration in-place.
9238            updateConfigurationLocked(configuration, null, false, true);
9239            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9240        }
9241    }
9242
9243    public boolean testIsSystemReady() {
9244        // no need to synchronize(this) just to read & return the value
9245        return mSystemReady;
9246    }
9247
9248    private static File getCalledPreBootReceiversFile() {
9249        File dataDir = Environment.getDataDirectory();
9250        File systemDir = new File(dataDir, "system");
9251        File fname = new File(systemDir, "called_pre_boots.dat");
9252        return fname;
9253    }
9254
9255    static final int LAST_DONE_VERSION = 10000;
9256
9257    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9258        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9259        File file = getCalledPreBootReceiversFile();
9260        FileInputStream fis = null;
9261        try {
9262            fis = new FileInputStream(file);
9263            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9264            int fvers = dis.readInt();
9265            if (fvers == LAST_DONE_VERSION) {
9266                String vers = dis.readUTF();
9267                String codename = dis.readUTF();
9268                String build = dis.readUTF();
9269                if (android.os.Build.VERSION.RELEASE.equals(vers)
9270                        && android.os.Build.VERSION.CODENAME.equals(codename)
9271                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9272                    int num = dis.readInt();
9273                    while (num > 0) {
9274                        num--;
9275                        String pkg = dis.readUTF();
9276                        String cls = dis.readUTF();
9277                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9278                    }
9279                }
9280            }
9281        } catch (FileNotFoundException e) {
9282        } catch (IOException e) {
9283            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9284        } finally {
9285            if (fis != null) {
9286                try {
9287                    fis.close();
9288                } catch (IOException e) {
9289                }
9290            }
9291        }
9292        return lastDoneReceivers;
9293    }
9294
9295    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9296        File file = getCalledPreBootReceiversFile();
9297        FileOutputStream fos = null;
9298        DataOutputStream dos = null;
9299        try {
9300            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9301            fos = new FileOutputStream(file);
9302            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9303            dos.writeInt(LAST_DONE_VERSION);
9304            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9305            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9306            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9307            dos.writeInt(list.size());
9308            for (int i=0; i<list.size(); i++) {
9309                dos.writeUTF(list.get(i).getPackageName());
9310                dos.writeUTF(list.get(i).getClassName());
9311            }
9312        } catch (IOException e) {
9313            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9314            file.delete();
9315        } finally {
9316            FileUtils.sync(fos);
9317            if (dos != null) {
9318                try {
9319                    dos.close();
9320                } catch (IOException e) {
9321                    // TODO Auto-generated catch block
9322                    e.printStackTrace();
9323                }
9324            }
9325        }
9326    }
9327
9328    public void systemReady(final Runnable goingCallback) {
9329        synchronized(this) {
9330            if (mSystemReady) {
9331                if (goingCallback != null) goingCallback.run();
9332                return;
9333            }
9334
9335            // Check to see if there are any update receivers to run.
9336            if (!mDidUpdate) {
9337                if (mWaitingUpdate) {
9338                    return;
9339                }
9340                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9341                List<ResolveInfo> ris = null;
9342                try {
9343                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9344                            intent, null, 0, 0);
9345                } catch (RemoteException e) {
9346                }
9347                if (ris != null) {
9348                    for (int i=ris.size()-1; i>=0; i--) {
9349                        if ((ris.get(i).activityInfo.applicationInfo.flags
9350                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9351                            ris.remove(i);
9352                        }
9353                    }
9354                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9355
9356                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9357
9358                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9359                    for (int i=0; i<ris.size(); i++) {
9360                        ActivityInfo ai = ris.get(i).activityInfo;
9361                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9362                        if (lastDoneReceivers.contains(comp)) {
9363                            // We already did the pre boot receiver for this app with the current
9364                            // platform version, so don't do it again...
9365                            ris.remove(i);
9366                            i--;
9367                            // ...however, do keep it as one that has been done, so we don't
9368                            // forget about it when rewriting the file of last done receivers.
9369                            doneReceivers.add(comp);
9370                        }
9371                    }
9372
9373                    final int[] users = getUsersLocked();
9374                    for (int i=0; i<ris.size(); i++) {
9375                        ActivityInfo ai = ris.get(i).activityInfo;
9376                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9377                        doneReceivers.add(comp);
9378                        intent.setComponent(comp);
9379                        for (int j=0; j<users.length; j++) {
9380                            IIntentReceiver finisher = null;
9381                            if (i == ris.size()-1 && j == users.length-1) {
9382                                finisher = new IIntentReceiver.Stub() {
9383                                    public void performReceive(Intent intent, int resultCode,
9384                                            String data, Bundle extras, boolean ordered,
9385                                            boolean sticky, int sendingUser) {
9386                                        // The raw IIntentReceiver interface is called
9387                                        // with the AM lock held, so redispatch to
9388                                        // execute our code without the lock.
9389                                        mHandler.post(new Runnable() {
9390                                            public void run() {
9391                                                synchronized (ActivityManagerService.this) {
9392                                                    mDidUpdate = true;
9393                                                }
9394                                                writeLastDonePreBootReceivers(doneReceivers);
9395                                                showBootMessage(mContext.getText(
9396                                                        R.string.android_upgrading_complete),
9397                                                        false);
9398                                                systemReady(goingCallback);
9399                                            }
9400                                        });
9401                                    }
9402                                };
9403                            }
9404                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9405                                    + " for user " + users[j]);
9406                            broadcastIntentLocked(null, null, intent, null, finisher,
9407                                    0, null, null, null, AppOpsManager.OP_NONE,
9408                                    true, false, MY_PID, Process.SYSTEM_UID,
9409                                    users[j]);
9410                            if (finisher != null) {
9411                                mWaitingUpdate = true;
9412                            }
9413                        }
9414                    }
9415                }
9416                if (mWaitingUpdate) {
9417                    return;
9418                }
9419                mDidUpdate = true;
9420            }
9421
9422            mAppOpsService.systemReady();
9423            mSystemReady = true;
9424            if (!mStartRunning) {
9425                return;
9426            }
9427        }
9428
9429        ArrayList<ProcessRecord> procsToKill = null;
9430        synchronized(mPidsSelfLocked) {
9431            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9432                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9433                if (!isAllowedWhileBooting(proc.info)){
9434                    if (procsToKill == null) {
9435                        procsToKill = new ArrayList<ProcessRecord>();
9436                    }
9437                    procsToKill.add(proc);
9438                }
9439            }
9440        }
9441
9442        synchronized(this) {
9443            if (procsToKill != null) {
9444                for (int i=procsToKill.size()-1; i>=0; i--) {
9445                    ProcessRecord proc = procsToKill.get(i);
9446                    Slog.i(TAG, "Removing system update proc: " + proc);
9447                    removeProcessLocked(proc, true, false, "system update done");
9448                }
9449            }
9450
9451            // Now that we have cleaned up any update processes, we
9452            // are ready to start launching real processes and know that
9453            // we won't trample on them any more.
9454            mProcessesReady = true;
9455        }
9456
9457        Slog.i(TAG, "System now ready");
9458        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9459            SystemClock.uptimeMillis());
9460
9461        synchronized(this) {
9462            // Make sure we have no pre-ready processes sitting around.
9463
9464            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9465                ResolveInfo ri = mContext.getPackageManager()
9466                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9467                                STOCK_PM_FLAGS);
9468                CharSequence errorMsg = null;
9469                if (ri != null) {
9470                    ActivityInfo ai = ri.activityInfo;
9471                    ApplicationInfo app = ai.applicationInfo;
9472                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9473                        mTopAction = Intent.ACTION_FACTORY_TEST;
9474                        mTopData = null;
9475                        mTopComponent = new ComponentName(app.packageName,
9476                                ai.name);
9477                    } else {
9478                        errorMsg = mContext.getResources().getText(
9479                                com.android.internal.R.string.factorytest_not_system);
9480                    }
9481                } else {
9482                    errorMsg = mContext.getResources().getText(
9483                            com.android.internal.R.string.factorytest_no_action);
9484                }
9485                if (errorMsg != null) {
9486                    mTopAction = null;
9487                    mTopData = null;
9488                    mTopComponent = null;
9489                    Message msg = Message.obtain();
9490                    msg.what = SHOW_FACTORY_ERROR_MSG;
9491                    msg.getData().putCharSequence("msg", errorMsg);
9492                    mHandler.sendMessage(msg);
9493                }
9494            }
9495        }
9496
9497        retrieveSettings();
9498
9499        synchronized (this) {
9500            readGrantedUriPermissionsLocked();
9501        }
9502
9503        if (goingCallback != null) goingCallback.run();
9504
9505        synchronized (this) {
9506            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9507                try {
9508                    List apps = AppGlobals.getPackageManager().
9509                        getPersistentApplications(STOCK_PM_FLAGS);
9510                    if (apps != null) {
9511                        int N = apps.size();
9512                        int i;
9513                        for (i=0; i<N; i++) {
9514                            ApplicationInfo info
9515                                = (ApplicationInfo)apps.get(i);
9516                            if (info != null &&
9517                                    !info.packageName.equals("android")) {
9518                                addAppLocked(info, false);
9519                            }
9520                        }
9521                    }
9522                } catch (RemoteException ex) {
9523                    // pm is in same process, this will never happen.
9524                }
9525            }
9526
9527            // Start up initial activity.
9528            mBooting = true;
9529
9530            try {
9531                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9532                    Message msg = Message.obtain();
9533                    msg.what = SHOW_UID_ERROR_MSG;
9534                    mHandler.sendMessage(msg);
9535                }
9536            } catch (RemoteException e) {
9537            }
9538
9539            long ident = Binder.clearCallingIdentity();
9540            try {
9541                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9542                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9543                        | Intent.FLAG_RECEIVER_FOREGROUND);
9544                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9545                broadcastIntentLocked(null, null, intent,
9546                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9547                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9548                intent = new Intent(Intent.ACTION_USER_STARTING);
9549                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9550                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9551                broadcastIntentLocked(null, null, intent,
9552                        null, new IIntentReceiver.Stub() {
9553                            @Override
9554                            public void performReceive(Intent intent, int resultCode, String data,
9555                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9556                                    throws RemoteException {
9557                            }
9558                        }, 0, null, null,
9559                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9560                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9561            } finally {
9562                Binder.restoreCallingIdentity(ident);
9563            }
9564            mStackSupervisor.resumeTopActivitiesLocked();
9565            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9566        }
9567    }
9568
9569    private boolean makeAppCrashingLocked(ProcessRecord app,
9570            String shortMsg, String longMsg, String stackTrace) {
9571        app.crashing = true;
9572        app.crashingReport = generateProcessError(app,
9573                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9574        startAppProblemLocked(app);
9575        app.stopFreezingAllLocked();
9576        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9577    }
9578
9579    private void makeAppNotRespondingLocked(ProcessRecord app,
9580            String activity, String shortMsg, String longMsg) {
9581        app.notResponding = true;
9582        app.notRespondingReport = generateProcessError(app,
9583                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9584                activity, shortMsg, longMsg, null);
9585        startAppProblemLocked(app);
9586        app.stopFreezingAllLocked();
9587    }
9588
9589    /**
9590     * Generate a process error record, suitable for attachment to a ProcessRecord.
9591     *
9592     * @param app The ProcessRecord in which the error occurred.
9593     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9594     *                      ActivityManager.AppErrorStateInfo
9595     * @param activity The activity associated with the crash, if known.
9596     * @param shortMsg Short message describing the crash.
9597     * @param longMsg Long message describing the crash.
9598     * @param stackTrace Full crash stack trace, may be null.
9599     *
9600     * @return Returns a fully-formed AppErrorStateInfo record.
9601     */
9602    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9603            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9604        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9605
9606        report.condition = condition;
9607        report.processName = app.processName;
9608        report.pid = app.pid;
9609        report.uid = app.info.uid;
9610        report.tag = activity;
9611        report.shortMsg = shortMsg;
9612        report.longMsg = longMsg;
9613        report.stackTrace = stackTrace;
9614
9615        return report;
9616    }
9617
9618    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9619        synchronized (this) {
9620            app.crashing = false;
9621            app.crashingReport = null;
9622            app.notResponding = false;
9623            app.notRespondingReport = null;
9624            if (app.anrDialog == fromDialog) {
9625                app.anrDialog = null;
9626            }
9627            if (app.waitDialog == fromDialog) {
9628                app.waitDialog = null;
9629            }
9630            if (app.pid > 0 && app.pid != MY_PID) {
9631                handleAppCrashLocked(app, null, null, null);
9632                killUnneededProcessLocked(app, "user request after error");
9633            }
9634        }
9635    }
9636
9637    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9638            String stackTrace) {
9639        long now = SystemClock.uptimeMillis();
9640
9641        Long crashTime;
9642        if (!app.isolated) {
9643            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9644        } else {
9645            crashTime = null;
9646        }
9647        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9648            // This process loses!
9649            Slog.w(TAG, "Process " + app.info.processName
9650                    + " has crashed too many times: killing!");
9651            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9652                    app.userId, app.info.processName, app.uid);
9653            mStackSupervisor.handleAppCrashLocked(app);
9654            if (!app.persistent) {
9655                // We don't want to start this process again until the user
9656                // explicitly does so...  but for persistent process, we really
9657                // need to keep it running.  If a persistent process is actually
9658                // repeatedly crashing, then badness for everyone.
9659                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9660                        app.info.processName);
9661                if (!app.isolated) {
9662                    // XXX We don't have a way to mark isolated processes
9663                    // as bad, since they don't have a peristent identity.
9664                    mBadProcesses.put(app.info.processName, app.uid,
9665                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9666                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9667                }
9668                app.bad = true;
9669                app.removed = true;
9670                // Don't let services in this process be restarted and potentially
9671                // annoy the user repeatedly.  Unless it is persistent, since those
9672                // processes run critical code.
9673                removeProcessLocked(app, false, false, "crash");
9674                mStackSupervisor.resumeTopActivitiesLocked();
9675                return false;
9676            }
9677            mStackSupervisor.resumeTopActivitiesLocked();
9678        } else {
9679            mStackSupervisor.finishTopRunningActivityLocked(app);
9680        }
9681
9682        // Bump up the crash count of any services currently running in the proc.
9683        for (int i=app.services.size()-1; i>=0; i--) {
9684            // Any services running in the application need to be placed
9685            // back in the pending list.
9686            ServiceRecord sr = app.services.valueAt(i);
9687            sr.crashCount++;
9688        }
9689
9690        // If the crashing process is what we consider to be the "home process" and it has been
9691        // replaced by a third-party app, clear the package preferred activities from packages
9692        // with a home activity running in the process to prevent a repeatedly crashing app
9693        // from blocking the user to manually clear the list.
9694        final ArrayList<ActivityRecord> activities = app.activities;
9695        if (app == mHomeProcess && activities.size() > 0
9696                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9697            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9698                final ActivityRecord r = activities.get(activityNdx);
9699                if (r.isHomeActivity()) {
9700                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9701                    try {
9702                        ActivityThread.getPackageManager()
9703                                .clearPackagePreferredActivities(r.packageName);
9704                    } catch (RemoteException c) {
9705                        // pm is in same process, this will never happen.
9706                    }
9707                }
9708            }
9709        }
9710
9711        if (!app.isolated) {
9712            // XXX Can't keep track of crash times for isolated processes,
9713            // because they don't have a perisistent identity.
9714            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9715        }
9716
9717        return true;
9718    }
9719
9720    void startAppProblemLocked(ProcessRecord app) {
9721        if (app.userId == mCurrentUserId) {
9722            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9723                    mContext, app.info.packageName, app.info.flags);
9724        } else {
9725            // If this app is not running under the current user, then we
9726            // can't give it a report button because that would require
9727            // launching the report UI under a different user.
9728            app.errorReportReceiver = null;
9729        }
9730        skipCurrentReceiverLocked(app);
9731    }
9732
9733    void skipCurrentReceiverLocked(ProcessRecord app) {
9734        for (BroadcastQueue queue : mBroadcastQueues) {
9735            queue.skipCurrentReceiverLocked(app);
9736        }
9737    }
9738
9739    /**
9740     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9741     * The application process will exit immediately after this call returns.
9742     * @param app object of the crashing app, null for the system server
9743     * @param crashInfo describing the exception
9744     */
9745    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9746        ProcessRecord r = findAppProcess(app, "Crash");
9747        final String processName = app == null ? "system_server"
9748                : (r == null ? "unknown" : r.processName);
9749
9750        handleApplicationCrashInner("crash", r, processName, crashInfo);
9751    }
9752
9753    /* Native crash reporting uses this inner version because it needs to be somewhat
9754     * decoupled from the AM-managed cleanup lifecycle
9755     */
9756    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9757            ApplicationErrorReport.CrashInfo crashInfo) {
9758        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9759                UserHandle.getUserId(Binder.getCallingUid()), processName,
9760                r == null ? -1 : r.info.flags,
9761                crashInfo.exceptionClassName,
9762                crashInfo.exceptionMessage,
9763                crashInfo.throwFileName,
9764                crashInfo.throwLineNumber);
9765
9766        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9767
9768        crashApplication(r, crashInfo);
9769    }
9770
9771    public void handleApplicationStrictModeViolation(
9772            IBinder app,
9773            int violationMask,
9774            StrictMode.ViolationInfo info) {
9775        ProcessRecord r = findAppProcess(app, "StrictMode");
9776        if (r == null) {
9777            return;
9778        }
9779
9780        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9781            Integer stackFingerprint = info.hashCode();
9782            boolean logIt = true;
9783            synchronized (mAlreadyLoggedViolatedStacks) {
9784                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9785                    logIt = false;
9786                    // TODO: sub-sample into EventLog for these, with
9787                    // the info.durationMillis?  Then we'd get
9788                    // the relative pain numbers, without logging all
9789                    // the stack traces repeatedly.  We'd want to do
9790                    // likewise in the client code, which also does
9791                    // dup suppression, before the Binder call.
9792                } else {
9793                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9794                        mAlreadyLoggedViolatedStacks.clear();
9795                    }
9796                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9797                }
9798            }
9799            if (logIt) {
9800                logStrictModeViolationToDropBox(r, info);
9801            }
9802        }
9803
9804        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9805            AppErrorResult result = new AppErrorResult();
9806            synchronized (this) {
9807                final long origId = Binder.clearCallingIdentity();
9808
9809                Message msg = Message.obtain();
9810                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9811                HashMap<String, Object> data = new HashMap<String, Object>();
9812                data.put("result", result);
9813                data.put("app", r);
9814                data.put("violationMask", violationMask);
9815                data.put("info", info);
9816                msg.obj = data;
9817                mHandler.sendMessage(msg);
9818
9819                Binder.restoreCallingIdentity(origId);
9820            }
9821            int res = result.get();
9822            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9823        }
9824    }
9825
9826    // Depending on the policy in effect, there could be a bunch of
9827    // these in quick succession so we try to batch these together to
9828    // minimize disk writes, number of dropbox entries, and maximize
9829    // compression, by having more fewer, larger records.
9830    private void logStrictModeViolationToDropBox(
9831            ProcessRecord process,
9832            StrictMode.ViolationInfo info) {
9833        if (info == null) {
9834            return;
9835        }
9836        final boolean isSystemApp = process == null ||
9837                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9838                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9839        final String processName = process == null ? "unknown" : process.processName;
9840        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9841        final DropBoxManager dbox = (DropBoxManager)
9842                mContext.getSystemService(Context.DROPBOX_SERVICE);
9843
9844        // Exit early if the dropbox isn't configured to accept this report type.
9845        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9846
9847        boolean bufferWasEmpty;
9848        boolean needsFlush;
9849        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9850        synchronized (sb) {
9851            bufferWasEmpty = sb.length() == 0;
9852            appendDropBoxProcessHeaders(process, processName, sb);
9853            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9854            sb.append("System-App: ").append(isSystemApp).append("\n");
9855            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9856            if (info.violationNumThisLoop != 0) {
9857                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9858            }
9859            if (info.numAnimationsRunning != 0) {
9860                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9861            }
9862            if (info.broadcastIntentAction != null) {
9863                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9864            }
9865            if (info.durationMillis != -1) {
9866                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9867            }
9868            if (info.numInstances != -1) {
9869                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9870            }
9871            if (info.tags != null) {
9872                for (String tag : info.tags) {
9873                    sb.append("Span-Tag: ").append(tag).append("\n");
9874                }
9875            }
9876            sb.append("\n");
9877            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9878                sb.append(info.crashInfo.stackTrace);
9879            }
9880            sb.append("\n");
9881
9882            // Only buffer up to ~64k.  Various logging bits truncate
9883            // things at 128k.
9884            needsFlush = (sb.length() > 64 * 1024);
9885        }
9886
9887        // Flush immediately if the buffer's grown too large, or this
9888        // is a non-system app.  Non-system apps are isolated with a
9889        // different tag & policy and not batched.
9890        //
9891        // Batching is useful during internal testing with
9892        // StrictMode settings turned up high.  Without batching,
9893        // thousands of separate files could be created on boot.
9894        if (!isSystemApp || needsFlush) {
9895            new Thread("Error dump: " + dropboxTag) {
9896                @Override
9897                public void run() {
9898                    String report;
9899                    synchronized (sb) {
9900                        report = sb.toString();
9901                        sb.delete(0, sb.length());
9902                        sb.trimToSize();
9903                    }
9904                    if (report.length() != 0) {
9905                        dbox.addText(dropboxTag, report);
9906                    }
9907                }
9908            }.start();
9909            return;
9910        }
9911
9912        // System app batching:
9913        if (!bufferWasEmpty) {
9914            // An existing dropbox-writing thread is outstanding, so
9915            // we don't need to start it up.  The existing thread will
9916            // catch the buffer appends we just did.
9917            return;
9918        }
9919
9920        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9921        // (After this point, we shouldn't access AMS internal data structures.)
9922        new Thread("Error dump: " + dropboxTag) {
9923            @Override
9924            public void run() {
9925                // 5 second sleep to let stacks arrive and be batched together
9926                try {
9927                    Thread.sleep(5000);  // 5 seconds
9928                } catch (InterruptedException e) {}
9929
9930                String errorReport;
9931                synchronized (mStrictModeBuffer) {
9932                    errorReport = mStrictModeBuffer.toString();
9933                    if (errorReport.length() == 0) {
9934                        return;
9935                    }
9936                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9937                    mStrictModeBuffer.trimToSize();
9938                }
9939                dbox.addText(dropboxTag, errorReport);
9940            }
9941        }.start();
9942    }
9943
9944    /**
9945     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9946     * @param app object of the crashing app, null for the system server
9947     * @param tag reported by the caller
9948     * @param crashInfo describing the context of the error
9949     * @return true if the process should exit immediately (WTF is fatal)
9950     */
9951    public boolean handleApplicationWtf(IBinder app, String tag,
9952            ApplicationErrorReport.CrashInfo crashInfo) {
9953        ProcessRecord r = findAppProcess(app, "WTF");
9954        final String processName = app == null ? "system_server"
9955                : (r == null ? "unknown" : r.processName);
9956
9957        EventLog.writeEvent(EventLogTags.AM_WTF,
9958                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9959                processName,
9960                r == null ? -1 : r.info.flags,
9961                tag, crashInfo.exceptionMessage);
9962
9963        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9964
9965        if (r != null && r.pid != Process.myPid() &&
9966                Settings.Global.getInt(mContext.getContentResolver(),
9967                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9968            crashApplication(r, crashInfo);
9969            return true;
9970        } else {
9971            return false;
9972        }
9973    }
9974
9975    /**
9976     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9977     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9978     */
9979    private ProcessRecord findAppProcess(IBinder app, String reason) {
9980        if (app == null) {
9981            return null;
9982        }
9983
9984        synchronized (this) {
9985            final int NP = mProcessNames.getMap().size();
9986            for (int ip=0; ip<NP; ip++) {
9987                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9988                final int NA = apps.size();
9989                for (int ia=0; ia<NA; ia++) {
9990                    ProcessRecord p = apps.valueAt(ia);
9991                    if (p.thread != null && p.thread.asBinder() == app) {
9992                        return p;
9993                    }
9994                }
9995            }
9996
9997            Slog.w(TAG, "Can't find mystery application for " + reason
9998                    + " from pid=" + Binder.getCallingPid()
9999                    + " uid=" + Binder.getCallingUid() + ": " + app);
10000            return null;
10001        }
10002    }
10003
10004    /**
10005     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10006     * to append various headers to the dropbox log text.
10007     */
10008    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10009            StringBuilder sb) {
10010        // Watchdog thread ends up invoking this function (with
10011        // a null ProcessRecord) to add the stack file to dropbox.
10012        // Do not acquire a lock on this (am) in such cases, as it
10013        // could cause a potential deadlock, if and when watchdog
10014        // is invoked due to unavailability of lock on am and it
10015        // would prevent watchdog from killing system_server.
10016        if (process == null) {
10017            sb.append("Process: ").append(processName).append("\n");
10018            return;
10019        }
10020        // Note: ProcessRecord 'process' is guarded by the service
10021        // instance.  (notably process.pkgList, which could otherwise change
10022        // concurrently during execution of this method)
10023        synchronized (this) {
10024            sb.append("Process: ").append(processName).append("\n");
10025            int flags = process.info.flags;
10026            IPackageManager pm = AppGlobals.getPackageManager();
10027            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10028            for (int ip=0; ip<process.pkgList.size(); ip++) {
10029                String pkg = process.pkgList.keyAt(ip);
10030                sb.append("Package: ").append(pkg);
10031                try {
10032                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10033                    if (pi != null) {
10034                        sb.append(" v").append(pi.versionCode);
10035                        if (pi.versionName != null) {
10036                            sb.append(" (").append(pi.versionName).append(")");
10037                        }
10038                    }
10039                } catch (RemoteException e) {
10040                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10041                }
10042                sb.append("\n");
10043            }
10044        }
10045    }
10046
10047    private static String processClass(ProcessRecord process) {
10048        if (process == null || process.pid == MY_PID) {
10049            return "system_server";
10050        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10051            return "system_app";
10052        } else {
10053            return "data_app";
10054        }
10055    }
10056
10057    /**
10058     * Write a description of an error (crash, WTF, ANR) to the drop box.
10059     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10060     * @param process which caused the error, null means the system server
10061     * @param activity which triggered the error, null if unknown
10062     * @param parent activity related to the error, null if unknown
10063     * @param subject line related to the error, null if absent
10064     * @param report in long form describing the error, null if absent
10065     * @param logFile to include in the report, null if none
10066     * @param crashInfo giving an application stack trace, null if absent
10067     */
10068    public void addErrorToDropBox(String eventType,
10069            ProcessRecord process, String processName, ActivityRecord activity,
10070            ActivityRecord parent, String subject,
10071            final String report, final File logFile,
10072            final ApplicationErrorReport.CrashInfo crashInfo) {
10073        // NOTE -- this must never acquire the ActivityManagerService lock,
10074        // otherwise the watchdog may be prevented from resetting the system.
10075
10076        final String dropboxTag = processClass(process) + "_" + eventType;
10077        final DropBoxManager dbox = (DropBoxManager)
10078                mContext.getSystemService(Context.DROPBOX_SERVICE);
10079
10080        // Exit early if the dropbox isn't configured to accept this report type.
10081        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10082
10083        final StringBuilder sb = new StringBuilder(1024);
10084        appendDropBoxProcessHeaders(process, processName, sb);
10085        if (activity != null) {
10086            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10087        }
10088        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10089            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10090        }
10091        if (parent != null && parent != activity) {
10092            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10093        }
10094        if (subject != null) {
10095            sb.append("Subject: ").append(subject).append("\n");
10096        }
10097        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10098        if (Debug.isDebuggerConnected()) {
10099            sb.append("Debugger: Connected\n");
10100        }
10101        sb.append("\n");
10102
10103        // Do the rest in a worker thread to avoid blocking the caller on I/O
10104        // (After this point, we shouldn't access AMS internal data structures.)
10105        Thread worker = new Thread("Error dump: " + dropboxTag) {
10106            @Override
10107            public void run() {
10108                if (report != null) {
10109                    sb.append(report);
10110                }
10111                if (logFile != null) {
10112                    try {
10113                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10114                                    "\n\n[[TRUNCATED]]"));
10115                    } catch (IOException e) {
10116                        Slog.e(TAG, "Error reading " + logFile, e);
10117                    }
10118                }
10119                if (crashInfo != null && crashInfo.stackTrace != null) {
10120                    sb.append(crashInfo.stackTrace);
10121                }
10122
10123                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10124                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10125                if (lines > 0) {
10126                    sb.append("\n");
10127
10128                    // Merge several logcat streams, and take the last N lines
10129                    InputStreamReader input = null;
10130                    try {
10131                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10132                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10133                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10134
10135                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10136                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10137                        input = new InputStreamReader(logcat.getInputStream());
10138
10139                        int num;
10140                        char[] buf = new char[8192];
10141                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10142                    } catch (IOException e) {
10143                        Slog.e(TAG, "Error running logcat", e);
10144                    } finally {
10145                        if (input != null) try { input.close(); } catch (IOException e) {}
10146                    }
10147                }
10148
10149                dbox.addText(dropboxTag, sb.toString());
10150            }
10151        };
10152
10153        if (process == null) {
10154            // If process is null, we are being called from some internal code
10155            // and may be about to die -- run this synchronously.
10156            worker.run();
10157        } else {
10158            worker.start();
10159        }
10160    }
10161
10162    /**
10163     * Bring up the "unexpected error" dialog box for a crashing app.
10164     * Deal with edge cases (intercepts from instrumented applications,
10165     * ActivityController, error intent receivers, that sort of thing).
10166     * @param r the application crashing
10167     * @param crashInfo describing the failure
10168     */
10169    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10170        long timeMillis = System.currentTimeMillis();
10171        String shortMsg = crashInfo.exceptionClassName;
10172        String longMsg = crashInfo.exceptionMessage;
10173        String stackTrace = crashInfo.stackTrace;
10174        if (shortMsg != null && longMsg != null) {
10175            longMsg = shortMsg + ": " + longMsg;
10176        } else if (shortMsg != null) {
10177            longMsg = shortMsg;
10178        }
10179
10180        AppErrorResult result = new AppErrorResult();
10181        synchronized (this) {
10182            if (mController != null) {
10183                try {
10184                    String name = r != null ? r.processName : null;
10185                    int pid = r != null ? r.pid : Binder.getCallingPid();
10186                    if (!mController.appCrashed(name, pid,
10187                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10188                        Slog.w(TAG, "Force-killing crashed app " + name
10189                                + " at watcher's request");
10190                        Process.killProcess(pid);
10191                        return;
10192                    }
10193                } catch (RemoteException e) {
10194                    mController = null;
10195                    Watchdog.getInstance().setActivityController(null);
10196                }
10197            }
10198
10199            final long origId = Binder.clearCallingIdentity();
10200
10201            // If this process is running instrumentation, finish it.
10202            if (r != null && r.instrumentationClass != null) {
10203                Slog.w(TAG, "Error in app " + r.processName
10204                      + " running instrumentation " + r.instrumentationClass + ":");
10205                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10206                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10207                Bundle info = new Bundle();
10208                info.putString("shortMsg", shortMsg);
10209                info.putString("longMsg", longMsg);
10210                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10211                Binder.restoreCallingIdentity(origId);
10212                return;
10213            }
10214
10215            // If we can't identify the process or it's already exceeded its crash quota,
10216            // quit right away without showing a crash dialog.
10217            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10218                Binder.restoreCallingIdentity(origId);
10219                return;
10220            }
10221
10222            Message msg = Message.obtain();
10223            msg.what = SHOW_ERROR_MSG;
10224            HashMap data = new HashMap();
10225            data.put("result", result);
10226            data.put("app", r);
10227            msg.obj = data;
10228            mHandler.sendMessage(msg);
10229
10230            Binder.restoreCallingIdentity(origId);
10231        }
10232
10233        int res = result.get();
10234
10235        Intent appErrorIntent = null;
10236        synchronized (this) {
10237            if (r != null && !r.isolated) {
10238                // XXX Can't keep track of crash time for isolated processes,
10239                // since they don't have a persistent identity.
10240                mProcessCrashTimes.put(r.info.processName, r.uid,
10241                        SystemClock.uptimeMillis());
10242            }
10243            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10244                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10245            }
10246        }
10247
10248        if (appErrorIntent != null) {
10249            try {
10250                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10251            } catch (ActivityNotFoundException e) {
10252                Slog.w(TAG, "bug report receiver dissappeared", e);
10253            }
10254        }
10255    }
10256
10257    Intent createAppErrorIntentLocked(ProcessRecord r,
10258            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10259        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10260        if (report == null) {
10261            return null;
10262        }
10263        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10264        result.setComponent(r.errorReportReceiver);
10265        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10266        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10267        return result;
10268    }
10269
10270    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10271            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10272        if (r.errorReportReceiver == null) {
10273            return null;
10274        }
10275
10276        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10277            return null;
10278        }
10279
10280        ApplicationErrorReport report = new ApplicationErrorReport();
10281        report.packageName = r.info.packageName;
10282        report.installerPackageName = r.errorReportReceiver.getPackageName();
10283        report.processName = r.processName;
10284        report.time = timeMillis;
10285        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10286
10287        if (r.crashing || r.forceCrashReport) {
10288            report.type = ApplicationErrorReport.TYPE_CRASH;
10289            report.crashInfo = crashInfo;
10290        } else if (r.notResponding) {
10291            report.type = ApplicationErrorReport.TYPE_ANR;
10292            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10293
10294            report.anrInfo.activity = r.notRespondingReport.tag;
10295            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10296            report.anrInfo.info = r.notRespondingReport.longMsg;
10297        }
10298
10299        return report;
10300    }
10301
10302    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10303        enforceNotIsolatedCaller("getProcessesInErrorState");
10304        // assume our apps are happy - lazy create the list
10305        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10306
10307        final boolean allUsers = ActivityManager.checkUidPermission(
10308                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10309                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10310        int userId = UserHandle.getUserId(Binder.getCallingUid());
10311
10312        synchronized (this) {
10313
10314            // iterate across all processes
10315            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10316                ProcessRecord app = mLruProcesses.get(i);
10317                if (!allUsers && app.userId != userId) {
10318                    continue;
10319                }
10320                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10321                    // This one's in trouble, so we'll generate a report for it
10322                    // crashes are higher priority (in case there's a crash *and* an anr)
10323                    ActivityManager.ProcessErrorStateInfo report = null;
10324                    if (app.crashing) {
10325                        report = app.crashingReport;
10326                    } else if (app.notResponding) {
10327                        report = app.notRespondingReport;
10328                    }
10329
10330                    if (report != null) {
10331                        if (errList == null) {
10332                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10333                        }
10334                        errList.add(report);
10335                    } else {
10336                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10337                                " crashing = " + app.crashing +
10338                                " notResponding = " + app.notResponding);
10339                    }
10340                }
10341            }
10342        }
10343
10344        return errList;
10345    }
10346
10347    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10348        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10349            if (currApp != null) {
10350                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10351            }
10352            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10353        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10354            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10355        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10356            if (currApp != null) {
10357                currApp.lru = 0;
10358            }
10359            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10360        } else if (adj >= ProcessList.SERVICE_ADJ) {
10361            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10362        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10363            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10364        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10365            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10366        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10367            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10368        } else {
10369            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10370        }
10371    }
10372
10373    private void fillInProcMemInfo(ProcessRecord app,
10374            ActivityManager.RunningAppProcessInfo outInfo) {
10375        outInfo.pid = app.pid;
10376        outInfo.uid = app.info.uid;
10377        if (mHeavyWeightProcess == app) {
10378            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10379        }
10380        if (app.persistent) {
10381            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10382        }
10383        if (app.activities.size() > 0) {
10384            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10385        }
10386        outInfo.lastTrimLevel = app.trimMemoryLevel;
10387        int adj = app.curAdj;
10388        outInfo.importance = oomAdjToImportance(adj, outInfo);
10389        outInfo.importanceReasonCode = app.adjTypeCode;
10390    }
10391
10392    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10393        enforceNotIsolatedCaller("getRunningAppProcesses");
10394        // Lazy instantiation of list
10395        List<ActivityManager.RunningAppProcessInfo> runList = null;
10396        final boolean allUsers = ActivityManager.checkUidPermission(
10397                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10398                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10399        int userId = UserHandle.getUserId(Binder.getCallingUid());
10400        synchronized (this) {
10401            // Iterate across all processes
10402            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10403                ProcessRecord app = mLruProcesses.get(i);
10404                if (!allUsers && app.userId != userId) {
10405                    continue;
10406                }
10407                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10408                    // Generate process state info for running application
10409                    ActivityManager.RunningAppProcessInfo currApp =
10410                        new ActivityManager.RunningAppProcessInfo(app.processName,
10411                                app.pid, app.getPackageList());
10412                    fillInProcMemInfo(app, currApp);
10413                    if (app.adjSource instanceof ProcessRecord) {
10414                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10415                        currApp.importanceReasonImportance = oomAdjToImportance(
10416                                app.adjSourceOom, null);
10417                    } else if (app.adjSource instanceof ActivityRecord) {
10418                        ActivityRecord r = (ActivityRecord)app.adjSource;
10419                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10420                    }
10421                    if (app.adjTarget instanceof ComponentName) {
10422                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10423                    }
10424                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10425                    //        + " lru=" + currApp.lru);
10426                    if (runList == null) {
10427                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10428                    }
10429                    runList.add(currApp);
10430                }
10431            }
10432        }
10433        return runList;
10434    }
10435
10436    public List<ApplicationInfo> getRunningExternalApplications() {
10437        enforceNotIsolatedCaller("getRunningExternalApplications");
10438        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10439        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10440        if (runningApps != null && runningApps.size() > 0) {
10441            Set<String> extList = new HashSet<String>();
10442            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10443                if (app.pkgList != null) {
10444                    for (String pkg : app.pkgList) {
10445                        extList.add(pkg);
10446                    }
10447                }
10448            }
10449            IPackageManager pm = AppGlobals.getPackageManager();
10450            for (String pkg : extList) {
10451                try {
10452                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10453                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10454                        retList.add(info);
10455                    }
10456                } catch (RemoteException e) {
10457                }
10458            }
10459        }
10460        return retList;
10461    }
10462
10463    @Override
10464    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10465        enforceNotIsolatedCaller("getMyMemoryState");
10466        synchronized (this) {
10467            ProcessRecord proc;
10468            synchronized (mPidsSelfLocked) {
10469                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10470            }
10471            fillInProcMemInfo(proc, outInfo);
10472        }
10473    }
10474
10475    @Override
10476    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10477        if (checkCallingPermission(android.Manifest.permission.DUMP)
10478                != PackageManager.PERMISSION_GRANTED) {
10479            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10480                    + Binder.getCallingPid()
10481                    + ", uid=" + Binder.getCallingUid()
10482                    + " without permission "
10483                    + android.Manifest.permission.DUMP);
10484            return;
10485        }
10486
10487        boolean dumpAll = false;
10488        boolean dumpClient = false;
10489        String dumpPackage = null;
10490
10491        int opti = 0;
10492        while (opti < args.length) {
10493            String opt = args[opti];
10494            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10495                break;
10496            }
10497            opti++;
10498            if ("-a".equals(opt)) {
10499                dumpAll = true;
10500            } else if ("-c".equals(opt)) {
10501                dumpClient = true;
10502            } else if ("-h".equals(opt)) {
10503                pw.println("Activity manager dump options:");
10504                pw.println("  [-a] [-c] [-h] [cmd] ...");
10505                pw.println("  cmd may be one of:");
10506                pw.println("    a[ctivities]: activity stack state");
10507                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10508                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10509                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10510                pw.println("    o[om]: out of memory management");
10511                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10512                pw.println("    provider [COMP_SPEC]: provider client-side state");
10513                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10514                pw.println("    service [COMP_SPEC]: service client-side state");
10515                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10516                pw.println("    all: dump all activities");
10517                pw.println("    top: dump the top activity");
10518                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10519                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10520                pw.println("    a partial substring in a component name, a");
10521                pw.println("    hex object identifier.");
10522                pw.println("  -a: include all available server state.");
10523                pw.println("  -c: include client state.");
10524                return;
10525            } else {
10526                pw.println("Unknown argument: " + opt + "; use -h for help");
10527            }
10528        }
10529
10530        long origId = Binder.clearCallingIdentity();
10531        boolean more = false;
10532        // Is the caller requesting to dump a particular piece of data?
10533        if (opti < args.length) {
10534            String cmd = args[opti];
10535            opti++;
10536            if ("activities".equals(cmd) || "a".equals(cmd)) {
10537                synchronized (this) {
10538                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10539                }
10540            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10541                String[] newArgs;
10542                String name;
10543                if (opti >= args.length) {
10544                    name = null;
10545                    newArgs = EMPTY_STRING_ARRAY;
10546                } else {
10547                    name = args[opti];
10548                    opti++;
10549                    newArgs = new String[args.length - opti];
10550                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10551                            args.length - opti);
10552                }
10553                synchronized (this) {
10554                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10555                }
10556            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10557                String[] newArgs;
10558                String name;
10559                if (opti >= args.length) {
10560                    name = null;
10561                    newArgs = EMPTY_STRING_ARRAY;
10562                } else {
10563                    name = args[opti];
10564                    opti++;
10565                    newArgs = new String[args.length - opti];
10566                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10567                            args.length - opti);
10568                }
10569                synchronized (this) {
10570                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10571                }
10572            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10573                String[] newArgs;
10574                String name;
10575                if (opti >= args.length) {
10576                    name = null;
10577                    newArgs = EMPTY_STRING_ARRAY;
10578                } else {
10579                    name = args[opti];
10580                    opti++;
10581                    newArgs = new String[args.length - opti];
10582                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10583                            args.length - opti);
10584                }
10585                synchronized (this) {
10586                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10587                }
10588            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10589                synchronized (this) {
10590                    dumpOomLocked(fd, pw, args, opti, true);
10591                }
10592            } else if ("provider".equals(cmd)) {
10593                String[] newArgs;
10594                String name;
10595                if (opti >= args.length) {
10596                    name = null;
10597                    newArgs = EMPTY_STRING_ARRAY;
10598                } else {
10599                    name = args[opti];
10600                    opti++;
10601                    newArgs = new String[args.length - opti];
10602                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10603                }
10604                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10605                    pw.println("No providers match: " + name);
10606                    pw.println("Use -h for help.");
10607                }
10608            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10609                synchronized (this) {
10610                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10611                }
10612            } else if ("service".equals(cmd)) {
10613                String[] newArgs;
10614                String name;
10615                if (opti >= args.length) {
10616                    name = null;
10617                    newArgs = EMPTY_STRING_ARRAY;
10618                } else {
10619                    name = args[opti];
10620                    opti++;
10621                    newArgs = new String[args.length - opti];
10622                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10623                            args.length - opti);
10624                }
10625                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10626                    pw.println("No services match: " + name);
10627                    pw.println("Use -h for help.");
10628                }
10629            } else if ("package".equals(cmd)) {
10630                String[] newArgs;
10631                if (opti >= args.length) {
10632                    pw.println("package: no package name specified");
10633                    pw.println("Use -h for help.");
10634                } else {
10635                    dumpPackage = args[opti];
10636                    opti++;
10637                    newArgs = new String[args.length - opti];
10638                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10639                            args.length - opti);
10640                    args = newArgs;
10641                    opti = 0;
10642                    more = true;
10643                }
10644            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10645                synchronized (this) {
10646                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10647                }
10648            } else {
10649                // Dumping a single activity?
10650                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10651                    pw.println("Bad activity command, or no activities match: " + cmd);
10652                    pw.println("Use -h for help.");
10653                }
10654            }
10655            if (!more) {
10656                Binder.restoreCallingIdentity(origId);
10657                return;
10658            }
10659        }
10660
10661        // No piece of data specified, dump everything.
10662        synchronized (this) {
10663            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10664            pw.println();
10665            if (dumpAll) {
10666                pw.println("-------------------------------------------------------------------------------");
10667            }
10668            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10669            pw.println();
10670            if (dumpAll) {
10671                pw.println("-------------------------------------------------------------------------------");
10672            }
10673            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10674            pw.println();
10675            if (dumpAll) {
10676                pw.println("-------------------------------------------------------------------------------");
10677            }
10678            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10679            pw.println();
10680            if (dumpAll) {
10681                pw.println("-------------------------------------------------------------------------------");
10682            }
10683            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10684            pw.println();
10685            if (dumpAll) {
10686                pw.println("-------------------------------------------------------------------------------");
10687            }
10688            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10689        }
10690        Binder.restoreCallingIdentity(origId);
10691    }
10692
10693    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10694            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10695        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10696
10697        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10698                dumpPackage);
10699        boolean needSep = printedAnything;
10700
10701        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10702                dumpPackage, needSep, "  mFocusedActivity: ");
10703        if (printed) {
10704            printedAnything = true;
10705            needSep = false;
10706        }
10707
10708        if (dumpPackage == null) {
10709            if (needSep) {
10710                pw.println();
10711            }
10712            needSep = true;
10713            printedAnything = true;
10714            mStackSupervisor.dump(pw, "  ");
10715        }
10716
10717        if (mRecentTasks.size() > 0) {
10718            boolean printedHeader = false;
10719
10720            final int N = mRecentTasks.size();
10721            for (int i=0; i<N; i++) {
10722                TaskRecord tr = mRecentTasks.get(i);
10723                if (dumpPackage != null) {
10724                    if (tr.realActivity == null ||
10725                            !dumpPackage.equals(tr.realActivity)) {
10726                        continue;
10727                    }
10728                }
10729                if (!printedHeader) {
10730                    if (needSep) {
10731                        pw.println();
10732                    }
10733                    pw.println("  Recent tasks:");
10734                    printedHeader = true;
10735                    printedAnything = true;
10736                }
10737                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10738                        pw.println(tr);
10739                if (dumpAll) {
10740                    mRecentTasks.get(i).dump(pw, "    ");
10741                }
10742            }
10743        }
10744
10745        if (!printedAnything) {
10746            pw.println("  (nothing)");
10747        }
10748    }
10749
10750    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10751            int opti, boolean dumpAll, String dumpPackage) {
10752        boolean needSep = false;
10753        boolean printedAnything = false;
10754        int numPers = 0;
10755
10756        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10757
10758        if (dumpAll) {
10759            final int NP = mProcessNames.getMap().size();
10760            for (int ip=0; ip<NP; ip++) {
10761                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10762                final int NA = procs.size();
10763                for (int ia=0; ia<NA; ia++) {
10764                    ProcessRecord r = procs.valueAt(ia);
10765                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10766                        continue;
10767                    }
10768                    if (!needSep) {
10769                        pw.println("  All known processes:");
10770                        needSep = true;
10771                        printedAnything = true;
10772                    }
10773                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10774                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10775                        pw.print(" "); pw.println(r);
10776                    r.dump(pw, "    ");
10777                    if (r.persistent) {
10778                        numPers++;
10779                    }
10780                }
10781            }
10782        }
10783
10784        if (mIsolatedProcesses.size() > 0) {
10785            boolean printed = false;
10786            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10787                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10788                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10789                    continue;
10790                }
10791                if (!printed) {
10792                    if (needSep) {
10793                        pw.println();
10794                    }
10795                    pw.println("  Isolated process list (sorted by uid):");
10796                    printedAnything = true;
10797                    printed = true;
10798                    needSep = true;
10799                }
10800                pw.println(String.format("%sIsolated #%2d: %s",
10801                        "    ", i, r.toString()));
10802            }
10803        }
10804
10805        if (mLruProcesses.size() > 0) {
10806            if (needSep) {
10807                pw.println();
10808            }
10809            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10810                    pw.print(" total, non-act at ");
10811                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10812                    pw.print(", non-svc at ");
10813                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10814                    pw.println("):");
10815            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10816            needSep = true;
10817            printedAnything = true;
10818        }
10819
10820        if (dumpAll || dumpPackage != null) {
10821            synchronized (mPidsSelfLocked) {
10822                boolean printed = false;
10823                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10824                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10825                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10826                        continue;
10827                    }
10828                    if (!printed) {
10829                        if (needSep) pw.println();
10830                        needSep = true;
10831                        pw.println("  PID mappings:");
10832                        printed = true;
10833                        printedAnything = true;
10834                    }
10835                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10836                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10837                }
10838            }
10839        }
10840
10841        if (mForegroundProcesses.size() > 0) {
10842            synchronized (mPidsSelfLocked) {
10843                boolean printed = false;
10844                for (int i=0; i<mForegroundProcesses.size(); i++) {
10845                    ProcessRecord r = mPidsSelfLocked.get(
10846                            mForegroundProcesses.valueAt(i).pid);
10847                    if (dumpPackage != null && (r == null
10848                            || !r.pkgList.containsKey(dumpPackage))) {
10849                        continue;
10850                    }
10851                    if (!printed) {
10852                        if (needSep) pw.println();
10853                        needSep = true;
10854                        pw.println("  Foreground Processes:");
10855                        printed = true;
10856                        printedAnything = true;
10857                    }
10858                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10859                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10860                }
10861            }
10862        }
10863
10864        if (mPersistentStartingProcesses.size() > 0) {
10865            if (needSep) pw.println();
10866            needSep = true;
10867            printedAnything = true;
10868            pw.println("  Persisent processes that are starting:");
10869            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10870                    "Starting Norm", "Restarting PERS", dumpPackage);
10871        }
10872
10873        if (mRemovedProcesses.size() > 0) {
10874            if (needSep) pw.println();
10875            needSep = true;
10876            printedAnything = true;
10877            pw.println("  Processes that are being removed:");
10878            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10879                    "Removed Norm", "Removed PERS", dumpPackage);
10880        }
10881
10882        if (mProcessesOnHold.size() > 0) {
10883            if (needSep) pw.println();
10884            needSep = true;
10885            printedAnything = true;
10886            pw.println("  Processes that are on old until the system is ready:");
10887            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10888                    "OnHold Norm", "OnHold PERS", dumpPackage);
10889        }
10890
10891        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10892
10893        if (mProcessCrashTimes.getMap().size() > 0) {
10894            boolean printed = false;
10895            long now = SystemClock.uptimeMillis();
10896            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10897            final int NP = pmap.size();
10898            for (int ip=0; ip<NP; ip++) {
10899                String pname = pmap.keyAt(ip);
10900                SparseArray<Long> uids = pmap.valueAt(ip);
10901                final int N = uids.size();
10902                for (int i=0; i<N; i++) {
10903                    int puid = uids.keyAt(i);
10904                    ProcessRecord r = mProcessNames.get(pname, puid);
10905                    if (dumpPackage != null && (r == null
10906                            || !r.pkgList.containsKey(dumpPackage))) {
10907                        continue;
10908                    }
10909                    if (!printed) {
10910                        if (needSep) pw.println();
10911                        needSep = true;
10912                        pw.println("  Time since processes crashed:");
10913                        printed = true;
10914                        printedAnything = true;
10915                    }
10916                    pw.print("    Process "); pw.print(pname);
10917                            pw.print(" uid "); pw.print(puid);
10918                            pw.print(": last crashed ");
10919                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10920                            pw.println(" ago");
10921                }
10922            }
10923        }
10924
10925        if (mBadProcesses.getMap().size() > 0) {
10926            boolean printed = false;
10927            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10928            final int NP = pmap.size();
10929            for (int ip=0; ip<NP; ip++) {
10930                String pname = pmap.keyAt(ip);
10931                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10932                final int N = uids.size();
10933                for (int i=0; i<N; i++) {
10934                    int puid = uids.keyAt(i);
10935                    ProcessRecord r = mProcessNames.get(pname, puid);
10936                    if (dumpPackage != null && (r == null
10937                            || !r.pkgList.containsKey(dumpPackage))) {
10938                        continue;
10939                    }
10940                    if (!printed) {
10941                        if (needSep) pw.println();
10942                        needSep = true;
10943                        pw.println("  Bad processes:");
10944                        printedAnything = true;
10945                    }
10946                    BadProcessInfo info = uids.valueAt(i);
10947                    pw.print("    Bad process "); pw.print(pname);
10948                            pw.print(" uid "); pw.print(puid);
10949                            pw.print(": crashed at time "); pw.println(info.time);
10950                    if (info.shortMsg != null) {
10951                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10952                    }
10953                    if (info.longMsg != null) {
10954                        pw.print("      Long msg: "); pw.println(info.longMsg);
10955                    }
10956                    if (info.stack != null) {
10957                        pw.println("      Stack:");
10958                        int lastPos = 0;
10959                        for (int pos=0; pos<info.stack.length(); pos++) {
10960                            if (info.stack.charAt(pos) == '\n') {
10961                                pw.print("        ");
10962                                pw.write(info.stack, lastPos, pos-lastPos);
10963                                pw.println();
10964                                lastPos = pos+1;
10965                            }
10966                        }
10967                        if (lastPos < info.stack.length()) {
10968                            pw.print("        ");
10969                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10970                            pw.println();
10971                        }
10972                    }
10973                }
10974            }
10975        }
10976
10977        if (dumpPackage == null) {
10978            pw.println();
10979            needSep = false;
10980            pw.println("  mStartedUsers:");
10981            for (int i=0; i<mStartedUsers.size(); i++) {
10982                UserStartedState uss = mStartedUsers.valueAt(i);
10983                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10984                        pw.print(": "); uss.dump("", pw);
10985            }
10986            pw.print("  mStartedUserArray: [");
10987            for (int i=0; i<mStartedUserArray.length; i++) {
10988                if (i > 0) pw.print(", ");
10989                pw.print(mStartedUserArray[i]);
10990            }
10991            pw.println("]");
10992            pw.print("  mUserLru: [");
10993            for (int i=0; i<mUserLru.size(); i++) {
10994                if (i > 0) pw.print(", ");
10995                pw.print(mUserLru.get(i));
10996            }
10997            pw.println("]");
10998            if (dumpAll) {
10999                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11000            }
11001        }
11002        if (mHomeProcess != null && (dumpPackage == null
11003                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11004            if (needSep) {
11005                pw.println();
11006                needSep = false;
11007            }
11008            pw.println("  mHomeProcess: " + mHomeProcess);
11009        }
11010        if (mPreviousProcess != null && (dumpPackage == null
11011                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11012            if (needSep) {
11013                pw.println();
11014                needSep = false;
11015            }
11016            pw.println("  mPreviousProcess: " + mPreviousProcess);
11017        }
11018        if (dumpAll) {
11019            StringBuilder sb = new StringBuilder(128);
11020            sb.append("  mPreviousProcessVisibleTime: ");
11021            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11022            pw.println(sb);
11023        }
11024        if (mHeavyWeightProcess != null && (dumpPackage == null
11025                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11026            if (needSep) {
11027                pw.println();
11028                needSep = false;
11029            }
11030            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11031        }
11032        if (dumpPackage == null) {
11033            pw.println("  mConfiguration: " + mConfiguration);
11034        }
11035        if (dumpAll) {
11036            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11037            if (mCompatModePackages.getPackages().size() > 0) {
11038                boolean printed = false;
11039                for (Map.Entry<String, Integer> entry
11040                        : mCompatModePackages.getPackages().entrySet()) {
11041                    String pkg = entry.getKey();
11042                    int mode = entry.getValue();
11043                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11044                        continue;
11045                    }
11046                    if (!printed) {
11047                        pw.println("  mScreenCompatPackages:");
11048                        printed = true;
11049                    }
11050                    pw.print("    "); pw.print(pkg); pw.print(": ");
11051                            pw.print(mode); pw.println();
11052                }
11053            }
11054        }
11055        if (dumpPackage == null) {
11056            if (mSleeping || mWentToSleep || mLockScreenShown) {
11057                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11058                        + " mLockScreenShown " + mLockScreenShown);
11059            }
11060            if (mShuttingDown) {
11061                pw.println("  mShuttingDown=" + mShuttingDown);
11062            }
11063        }
11064        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11065                || mOrigWaitForDebugger) {
11066            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11067                    || dumpPackage.equals(mOrigDebugApp)) {
11068                if (needSep) {
11069                    pw.println();
11070                    needSep = false;
11071                }
11072                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11073                        + " mDebugTransient=" + mDebugTransient
11074                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11075            }
11076        }
11077        if (mOpenGlTraceApp != null) {
11078            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11079                if (needSep) {
11080                    pw.println();
11081                    needSep = false;
11082                }
11083                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11084            }
11085        }
11086        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11087                || mProfileFd != null) {
11088            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11089                if (needSep) {
11090                    pw.println();
11091                    needSep = false;
11092                }
11093                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11094                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11095                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11096                        + mAutoStopProfiler);
11097            }
11098        }
11099        if (dumpPackage == null) {
11100            if (mAlwaysFinishActivities || mController != null) {
11101                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11102                        + " mController=" + mController);
11103            }
11104            if (dumpAll) {
11105                pw.println("  Total persistent processes: " + numPers);
11106                pw.println("  mStartRunning=" + mStartRunning
11107                        + " mProcessesReady=" + mProcessesReady
11108                        + " mSystemReady=" + mSystemReady);
11109                pw.println("  mBooting=" + mBooting
11110                        + " mBooted=" + mBooted
11111                        + " mFactoryTest=" + mFactoryTest);
11112                pw.print("  mLastPowerCheckRealtime=");
11113                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11114                        pw.println("");
11115                pw.print("  mLastPowerCheckUptime=");
11116                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11117                        pw.println("");
11118                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11119                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11120                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11121                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11122                        + " (" + mLruProcesses.size() + " total)"
11123                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11124                        + " mNumServiceProcs=" + mNumServiceProcs
11125                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11126                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11127                        + " mLastMemoryLevel" + mLastMemoryLevel
11128                        + " mLastNumProcesses" + mLastNumProcesses);
11129                long now = SystemClock.uptimeMillis();
11130                pw.print("  mLastIdleTime=");
11131                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11132                        pw.print(" mLowRamSinceLastIdle=");
11133                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11134                        pw.println();
11135            }
11136        }
11137
11138        if (!printedAnything) {
11139            pw.println("  (nothing)");
11140        }
11141    }
11142
11143    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11144            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11145        if (mProcessesToGc.size() > 0) {
11146            boolean printed = false;
11147            long now = SystemClock.uptimeMillis();
11148            for (int i=0; i<mProcessesToGc.size(); i++) {
11149                ProcessRecord proc = mProcessesToGc.get(i);
11150                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11151                    continue;
11152                }
11153                if (!printed) {
11154                    if (needSep) pw.println();
11155                    needSep = true;
11156                    pw.println("  Processes that are waiting to GC:");
11157                    printed = true;
11158                }
11159                pw.print("    Process "); pw.println(proc);
11160                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11161                        pw.print(", last gced=");
11162                        pw.print(now-proc.lastRequestedGc);
11163                        pw.print(" ms ago, last lowMem=");
11164                        pw.print(now-proc.lastLowMemory);
11165                        pw.println(" ms ago");
11166
11167            }
11168        }
11169        return needSep;
11170    }
11171
11172    void printOomLevel(PrintWriter pw, String name, int adj) {
11173        pw.print("    ");
11174        if (adj >= 0) {
11175            pw.print(' ');
11176            if (adj < 10) pw.print(' ');
11177        } else {
11178            if (adj > -10) pw.print(' ');
11179        }
11180        pw.print(adj);
11181        pw.print(": ");
11182        pw.print(name);
11183        pw.print(" (");
11184        pw.print(mProcessList.getMemLevel(adj)/1024);
11185        pw.println(" kB)");
11186    }
11187
11188    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11189            int opti, boolean dumpAll) {
11190        boolean needSep = false;
11191
11192        if (mLruProcesses.size() > 0) {
11193            if (needSep) pw.println();
11194            needSep = true;
11195            pw.println("  OOM levels:");
11196            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11197            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11198            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11199            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11200            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11201            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11202            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11203            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11204            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11205            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11206            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11207            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11208            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11209
11210            if (needSep) pw.println();
11211            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11212                    pw.print(" total, non-act at ");
11213                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11214                    pw.print(", non-svc at ");
11215                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11216                    pw.println("):");
11217            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11218            needSep = true;
11219        }
11220
11221        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11222
11223        pw.println();
11224        pw.println("  mHomeProcess: " + mHomeProcess);
11225        pw.println("  mPreviousProcess: " + mPreviousProcess);
11226        if (mHeavyWeightProcess != null) {
11227            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11228        }
11229
11230        return true;
11231    }
11232
11233    /**
11234     * There are three ways to call this:
11235     *  - no provider specified: dump all the providers
11236     *  - a flattened component name that matched an existing provider was specified as the
11237     *    first arg: dump that one provider
11238     *  - the first arg isn't the flattened component name of an existing provider:
11239     *    dump all providers whose component contains the first arg as a substring
11240     */
11241    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11242            int opti, boolean dumpAll) {
11243        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11244    }
11245
11246    static class ItemMatcher {
11247        ArrayList<ComponentName> components;
11248        ArrayList<String> strings;
11249        ArrayList<Integer> objects;
11250        boolean all;
11251
11252        ItemMatcher() {
11253            all = true;
11254        }
11255
11256        void build(String name) {
11257            ComponentName componentName = ComponentName.unflattenFromString(name);
11258            if (componentName != null) {
11259                if (components == null) {
11260                    components = new ArrayList<ComponentName>();
11261                }
11262                components.add(componentName);
11263                all = false;
11264            } else {
11265                int objectId = 0;
11266                // Not a '/' separated full component name; maybe an object ID?
11267                try {
11268                    objectId = Integer.parseInt(name, 16);
11269                    if (objects == null) {
11270                        objects = new ArrayList<Integer>();
11271                    }
11272                    objects.add(objectId);
11273                    all = false;
11274                } catch (RuntimeException e) {
11275                    // Not an integer; just do string match.
11276                    if (strings == null) {
11277                        strings = new ArrayList<String>();
11278                    }
11279                    strings.add(name);
11280                    all = false;
11281                }
11282            }
11283        }
11284
11285        int build(String[] args, int opti) {
11286            for (; opti<args.length; opti++) {
11287                String name = args[opti];
11288                if ("--".equals(name)) {
11289                    return opti+1;
11290                }
11291                build(name);
11292            }
11293            return opti;
11294        }
11295
11296        boolean match(Object object, ComponentName comp) {
11297            if (all) {
11298                return true;
11299            }
11300            if (components != null) {
11301                for (int i=0; i<components.size(); i++) {
11302                    if (components.get(i).equals(comp)) {
11303                        return true;
11304                    }
11305                }
11306            }
11307            if (objects != null) {
11308                for (int i=0; i<objects.size(); i++) {
11309                    if (System.identityHashCode(object) == objects.get(i)) {
11310                        return true;
11311                    }
11312                }
11313            }
11314            if (strings != null) {
11315                String flat = comp.flattenToString();
11316                for (int i=0; i<strings.size(); i++) {
11317                    if (flat.contains(strings.get(i))) {
11318                        return true;
11319                    }
11320                }
11321            }
11322            return false;
11323        }
11324    }
11325
11326    /**
11327     * There are three things that cmd can be:
11328     *  - a flattened component name that matches an existing activity
11329     *  - the cmd arg isn't the flattened component name of an existing activity:
11330     *    dump all activity whose component contains the cmd as a substring
11331     *  - A hex number of the ActivityRecord object instance.
11332     */
11333    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11334            int opti, boolean dumpAll) {
11335        ArrayList<ActivityRecord> activities;
11336
11337        synchronized (this) {
11338            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11339        }
11340
11341        if (activities.size() <= 0) {
11342            return false;
11343        }
11344
11345        String[] newArgs = new String[args.length - opti];
11346        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11347
11348        TaskRecord lastTask = null;
11349        boolean needSep = false;
11350        for (int i=activities.size()-1; i>=0; i--) {
11351            ActivityRecord r = activities.get(i);
11352            if (needSep) {
11353                pw.println();
11354            }
11355            needSep = true;
11356            synchronized (this) {
11357                if (lastTask != r.task) {
11358                    lastTask = r.task;
11359                    pw.print("TASK "); pw.print(lastTask.affinity);
11360                            pw.print(" id="); pw.println(lastTask.taskId);
11361                    if (dumpAll) {
11362                        lastTask.dump(pw, "  ");
11363                    }
11364                }
11365            }
11366            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11367        }
11368        return true;
11369    }
11370
11371    /**
11372     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11373     * there is a thread associated with the activity.
11374     */
11375    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11376            final ActivityRecord r, String[] args, boolean dumpAll) {
11377        String innerPrefix = prefix + "  ";
11378        synchronized (this) {
11379            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11380                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11381                    pw.print(" pid=");
11382                    if (r.app != null) pw.println(r.app.pid);
11383                    else pw.println("(not running)");
11384            if (dumpAll) {
11385                r.dump(pw, innerPrefix);
11386            }
11387        }
11388        if (r.app != null && r.app.thread != null) {
11389            // flush anything that is already in the PrintWriter since the thread is going
11390            // to write to the file descriptor directly
11391            pw.flush();
11392            try {
11393                TransferPipe tp = new TransferPipe();
11394                try {
11395                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11396                            r.appToken, innerPrefix, args);
11397                    tp.go(fd);
11398                } finally {
11399                    tp.kill();
11400                }
11401            } catch (IOException e) {
11402                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11403            } catch (RemoteException e) {
11404                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11405            }
11406        }
11407    }
11408
11409    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11410            int opti, boolean dumpAll, String dumpPackage) {
11411        boolean needSep = false;
11412        boolean onlyHistory = false;
11413        boolean printedAnything = false;
11414
11415        if ("history".equals(dumpPackage)) {
11416            if (opti < args.length && "-s".equals(args[opti])) {
11417                dumpAll = false;
11418            }
11419            onlyHistory = true;
11420            dumpPackage = null;
11421        }
11422
11423        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11424        if (!onlyHistory && dumpAll) {
11425            if (mRegisteredReceivers.size() > 0) {
11426                boolean printed = false;
11427                Iterator it = mRegisteredReceivers.values().iterator();
11428                while (it.hasNext()) {
11429                    ReceiverList r = (ReceiverList)it.next();
11430                    if (dumpPackage != null && (r.app == null ||
11431                            !dumpPackage.equals(r.app.info.packageName))) {
11432                        continue;
11433                    }
11434                    if (!printed) {
11435                        pw.println("  Registered Receivers:");
11436                        needSep = true;
11437                        printed = true;
11438                        printedAnything = true;
11439                    }
11440                    pw.print("  * "); pw.println(r);
11441                    r.dump(pw, "    ");
11442                }
11443            }
11444
11445            if (mReceiverResolver.dump(pw, needSep ?
11446                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11447                    "    ", dumpPackage, false)) {
11448                needSep = true;
11449                printedAnything = true;
11450            }
11451        }
11452
11453        for (BroadcastQueue q : mBroadcastQueues) {
11454            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11455            printedAnything |= needSep;
11456        }
11457
11458        needSep = true;
11459
11460        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11461            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11462                if (needSep) {
11463                    pw.println();
11464                }
11465                needSep = true;
11466                printedAnything = true;
11467                pw.print("  Sticky broadcasts for user ");
11468                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11469                StringBuilder sb = new StringBuilder(128);
11470                for (Map.Entry<String, ArrayList<Intent>> ent
11471                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11472                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11473                    if (dumpAll) {
11474                        pw.println(":");
11475                        ArrayList<Intent> intents = ent.getValue();
11476                        final int N = intents.size();
11477                        for (int i=0; i<N; i++) {
11478                            sb.setLength(0);
11479                            sb.append("    Intent: ");
11480                            intents.get(i).toShortString(sb, false, true, false, false);
11481                            pw.println(sb.toString());
11482                            Bundle bundle = intents.get(i).getExtras();
11483                            if (bundle != null) {
11484                                pw.print("      ");
11485                                pw.println(bundle.toString());
11486                            }
11487                        }
11488                    } else {
11489                        pw.println("");
11490                    }
11491                }
11492            }
11493        }
11494
11495        if (!onlyHistory && dumpAll) {
11496            pw.println();
11497            for (BroadcastQueue queue : mBroadcastQueues) {
11498                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11499                        + queue.mBroadcastsScheduled);
11500            }
11501            pw.println("  mHandler:");
11502            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11503            needSep = true;
11504            printedAnything = true;
11505        }
11506
11507        if (!printedAnything) {
11508            pw.println("  (nothing)");
11509        }
11510    }
11511
11512    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11513            int opti, boolean dumpAll, String dumpPackage) {
11514        boolean needSep;
11515        boolean printedAnything = false;
11516
11517        ItemMatcher matcher = new ItemMatcher();
11518        matcher.build(args, opti);
11519
11520        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11521
11522        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11523        printedAnything |= needSep;
11524
11525        if (mLaunchingProviders.size() > 0) {
11526            boolean printed = false;
11527            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11528                ContentProviderRecord r = mLaunchingProviders.get(i);
11529                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11530                    continue;
11531                }
11532                if (!printed) {
11533                    if (needSep) pw.println();
11534                    needSep = true;
11535                    pw.println("  Launching content providers:");
11536                    printed = true;
11537                    printedAnything = true;
11538                }
11539                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11540                        pw.println(r);
11541            }
11542        }
11543
11544        if (mGrantedUriPermissions.size() > 0) {
11545            boolean printed = false;
11546            int dumpUid = -2;
11547            if (dumpPackage != null) {
11548                try {
11549                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11550                } catch (NameNotFoundException e) {
11551                    dumpUid = -1;
11552                }
11553            }
11554            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11555                int uid = mGrantedUriPermissions.keyAt(i);
11556                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11557                    continue;
11558                }
11559                ArrayMap<Uri, UriPermission> perms
11560                        = mGrantedUriPermissions.valueAt(i);
11561                if (!printed) {
11562                    if (needSep) pw.println();
11563                    needSep = true;
11564                    pw.println("  Granted Uri Permissions:");
11565                    printed = true;
11566                    printedAnything = true;
11567                }
11568                pw.print("  * UID "); pw.print(uid);
11569                        pw.println(" holds:");
11570                for (UriPermission perm : perms.values()) {
11571                    pw.print("    "); pw.println(perm);
11572                    if (dumpAll) {
11573                        perm.dump(pw, "      ");
11574                    }
11575                }
11576            }
11577        }
11578
11579        if (!printedAnything) {
11580            pw.println("  (nothing)");
11581        }
11582    }
11583
11584    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11585            int opti, boolean dumpAll, String dumpPackage) {
11586        boolean printed = false;
11587
11588        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11589
11590        if (mIntentSenderRecords.size() > 0) {
11591            Iterator<WeakReference<PendingIntentRecord>> it
11592                    = mIntentSenderRecords.values().iterator();
11593            while (it.hasNext()) {
11594                WeakReference<PendingIntentRecord> ref = it.next();
11595                PendingIntentRecord rec = ref != null ? ref.get(): null;
11596                if (dumpPackage != null && (rec == null
11597                        || !dumpPackage.equals(rec.key.packageName))) {
11598                    continue;
11599                }
11600                printed = true;
11601                if (rec != null) {
11602                    pw.print("  * "); pw.println(rec);
11603                    if (dumpAll) {
11604                        rec.dump(pw, "    ");
11605                    }
11606                } else {
11607                    pw.print("  * "); pw.println(ref);
11608                }
11609            }
11610        }
11611
11612        if (!printed) {
11613            pw.println("  (nothing)");
11614        }
11615    }
11616
11617    private static final int dumpProcessList(PrintWriter pw,
11618            ActivityManagerService service, List list,
11619            String prefix, String normalLabel, String persistentLabel,
11620            String dumpPackage) {
11621        int numPers = 0;
11622        final int N = list.size()-1;
11623        for (int i=N; i>=0; i--) {
11624            ProcessRecord r = (ProcessRecord)list.get(i);
11625            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11626                continue;
11627            }
11628            pw.println(String.format("%s%s #%2d: %s",
11629                    prefix, (r.persistent ? persistentLabel : normalLabel),
11630                    i, r.toString()));
11631            if (r.persistent) {
11632                numPers++;
11633            }
11634        }
11635        return numPers;
11636    }
11637
11638    private static final boolean dumpProcessOomList(PrintWriter pw,
11639            ActivityManagerService service, List<ProcessRecord> origList,
11640            String prefix, String normalLabel, String persistentLabel,
11641            boolean inclDetails, String dumpPackage) {
11642
11643        ArrayList<Pair<ProcessRecord, Integer>> list
11644                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11645        for (int i=0; i<origList.size(); i++) {
11646            ProcessRecord r = origList.get(i);
11647            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11648                continue;
11649            }
11650            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11651        }
11652
11653        if (list.size() <= 0) {
11654            return false;
11655        }
11656
11657        Comparator<Pair<ProcessRecord, Integer>> comparator
11658                = new Comparator<Pair<ProcessRecord, Integer>>() {
11659            @Override
11660            public int compare(Pair<ProcessRecord, Integer> object1,
11661                    Pair<ProcessRecord, Integer> object2) {
11662                if (object1.first.setAdj != object2.first.setAdj) {
11663                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11664                }
11665                if (object1.second.intValue() != object2.second.intValue()) {
11666                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11667                }
11668                return 0;
11669            }
11670        };
11671
11672        Collections.sort(list, comparator);
11673
11674        final long curRealtime = SystemClock.elapsedRealtime();
11675        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11676        final long curUptime = SystemClock.uptimeMillis();
11677        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11678
11679        for (int i=list.size()-1; i>=0; i--) {
11680            ProcessRecord r = list.get(i).first;
11681            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11682            char schedGroup;
11683            switch (r.setSchedGroup) {
11684                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11685                    schedGroup = 'B';
11686                    break;
11687                case Process.THREAD_GROUP_DEFAULT:
11688                    schedGroup = 'F';
11689                    break;
11690                default:
11691                    schedGroup = '?';
11692                    break;
11693            }
11694            char foreground;
11695            if (r.foregroundActivities) {
11696                foreground = 'A';
11697            } else if (r.foregroundServices) {
11698                foreground = 'S';
11699            } else {
11700                foreground = ' ';
11701            }
11702            String procState = ProcessList.makeProcStateString(r.curProcState);
11703            pw.print(prefix);
11704            pw.print(r.persistent ? persistentLabel : normalLabel);
11705            pw.print(" #");
11706            int num = (origList.size()-1)-list.get(i).second;
11707            if (num < 10) pw.print(' ');
11708            pw.print(num);
11709            pw.print(": ");
11710            pw.print(oomAdj);
11711            pw.print(' ');
11712            pw.print(schedGroup);
11713            pw.print('/');
11714            pw.print(foreground);
11715            pw.print('/');
11716            pw.print(procState);
11717            pw.print(" trm:");
11718            if (r.trimMemoryLevel < 10) pw.print(' ');
11719            pw.print(r.trimMemoryLevel);
11720            pw.print(' ');
11721            pw.print(r.toShortString());
11722            pw.print(" (");
11723            pw.print(r.adjType);
11724            pw.println(')');
11725            if (r.adjSource != null || r.adjTarget != null) {
11726                pw.print(prefix);
11727                pw.print("    ");
11728                if (r.adjTarget instanceof ComponentName) {
11729                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11730                } else if (r.adjTarget != null) {
11731                    pw.print(r.adjTarget.toString());
11732                } else {
11733                    pw.print("{null}");
11734                }
11735                pw.print("<=");
11736                if (r.adjSource instanceof ProcessRecord) {
11737                    pw.print("Proc{");
11738                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11739                    pw.println("}");
11740                } else if (r.adjSource != null) {
11741                    pw.println(r.adjSource.toString());
11742                } else {
11743                    pw.println("{null}");
11744                }
11745            }
11746            if (inclDetails) {
11747                pw.print(prefix);
11748                pw.print("    ");
11749                pw.print("oom: max="); pw.print(r.maxAdj);
11750                pw.print(" curRaw="); pw.print(r.curRawAdj);
11751                pw.print(" setRaw="); pw.print(r.setRawAdj);
11752                pw.print(" cur="); pw.print(r.curAdj);
11753                pw.print(" set="); pw.println(r.setAdj);
11754                pw.print(prefix);
11755                pw.print("    ");
11756                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11757                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11758                pw.print(" lastPss="); pw.print(r.lastPss);
11759                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11760                pw.print(prefix);
11761                pw.print("    ");
11762                pw.print("keeping="); pw.print(r.keeping);
11763                pw.print(" cached="); pw.print(r.cached);
11764                pw.print(" empty="); pw.print(r.empty);
11765                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11766
11767                if (!r.keeping) {
11768                    if (r.lastWakeTime != 0) {
11769                        long wtime;
11770                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11771                        synchronized (stats) {
11772                            wtime = stats.getProcessWakeTime(r.info.uid,
11773                                    r.pid, curRealtime);
11774                        }
11775                        long timeUsed = wtime - r.lastWakeTime;
11776                        pw.print(prefix);
11777                        pw.print("    ");
11778                        pw.print("keep awake over ");
11779                        TimeUtils.formatDuration(realtimeSince, pw);
11780                        pw.print(" used ");
11781                        TimeUtils.formatDuration(timeUsed, pw);
11782                        pw.print(" (");
11783                        pw.print((timeUsed*100)/realtimeSince);
11784                        pw.println("%)");
11785                    }
11786                    if (r.lastCpuTime != 0) {
11787                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11788                        pw.print(prefix);
11789                        pw.print("    ");
11790                        pw.print("run cpu over ");
11791                        TimeUtils.formatDuration(uptimeSince, pw);
11792                        pw.print(" used ");
11793                        TimeUtils.formatDuration(timeUsed, pw);
11794                        pw.print(" (");
11795                        pw.print((timeUsed*100)/uptimeSince);
11796                        pw.println("%)");
11797                    }
11798                }
11799            }
11800        }
11801        return true;
11802    }
11803
11804    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11805        ArrayList<ProcessRecord> procs;
11806        synchronized (this) {
11807            if (args != null && args.length > start
11808                    && args[start].charAt(0) != '-') {
11809                procs = new ArrayList<ProcessRecord>();
11810                int pid = -1;
11811                try {
11812                    pid = Integer.parseInt(args[start]);
11813                } catch (NumberFormatException e) {
11814                }
11815                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11816                    ProcessRecord proc = mLruProcesses.get(i);
11817                    if (proc.pid == pid) {
11818                        procs.add(proc);
11819                    } else if (proc.processName.equals(args[start])) {
11820                        procs.add(proc);
11821                    }
11822                }
11823                if (procs.size() <= 0) {
11824                    return null;
11825                }
11826            } else {
11827                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11828            }
11829        }
11830        return procs;
11831    }
11832
11833    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11834            PrintWriter pw, String[] args) {
11835        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11836        if (procs == null) {
11837            pw.println("No process found for: " + args[0]);
11838            return;
11839        }
11840
11841        long uptime = SystemClock.uptimeMillis();
11842        long realtime = SystemClock.elapsedRealtime();
11843        pw.println("Applications Graphics Acceleration Info:");
11844        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11845
11846        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11847            ProcessRecord r = procs.get(i);
11848            if (r.thread != null) {
11849                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11850                pw.flush();
11851                try {
11852                    TransferPipe tp = new TransferPipe();
11853                    try {
11854                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11855                        tp.go(fd);
11856                    } finally {
11857                        tp.kill();
11858                    }
11859                } catch (IOException e) {
11860                    pw.println("Failure while dumping the app: " + r);
11861                    pw.flush();
11862                } catch (RemoteException e) {
11863                    pw.println("Got a RemoteException while dumping the app " + r);
11864                    pw.flush();
11865                }
11866            }
11867        }
11868    }
11869
11870    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11871        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11872        if (procs == null) {
11873            pw.println("No process found for: " + args[0]);
11874            return;
11875        }
11876
11877        pw.println("Applications Database Info:");
11878
11879        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11880            ProcessRecord r = procs.get(i);
11881            if (r.thread != null) {
11882                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11883                pw.flush();
11884                try {
11885                    TransferPipe tp = new TransferPipe();
11886                    try {
11887                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11888                        tp.go(fd);
11889                    } finally {
11890                        tp.kill();
11891                    }
11892                } catch (IOException e) {
11893                    pw.println("Failure while dumping the app: " + r);
11894                    pw.flush();
11895                } catch (RemoteException e) {
11896                    pw.println("Got a RemoteException while dumping the app " + r);
11897                    pw.flush();
11898                }
11899            }
11900        }
11901    }
11902
11903    final static class MemItem {
11904        final boolean isProc;
11905        final String label;
11906        final String shortLabel;
11907        final long pss;
11908        final int id;
11909        final boolean hasActivities;
11910        ArrayList<MemItem> subitems;
11911
11912        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11913                boolean _hasActivities) {
11914            isProc = true;
11915            label = _label;
11916            shortLabel = _shortLabel;
11917            pss = _pss;
11918            id = _id;
11919            hasActivities = _hasActivities;
11920        }
11921
11922        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11923            isProc = false;
11924            label = _label;
11925            shortLabel = _shortLabel;
11926            pss = _pss;
11927            id = _id;
11928            hasActivities = false;
11929        }
11930    }
11931
11932    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11933            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11934        if (sort && !isCompact) {
11935            Collections.sort(items, new Comparator<MemItem>() {
11936                @Override
11937                public int compare(MemItem lhs, MemItem rhs) {
11938                    if (lhs.pss < rhs.pss) {
11939                        return 1;
11940                    } else if (lhs.pss > rhs.pss) {
11941                        return -1;
11942                    }
11943                    return 0;
11944                }
11945            });
11946        }
11947
11948        for (int i=0; i<items.size(); i++) {
11949            MemItem mi = items.get(i);
11950            if (!isCompact) {
11951                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11952            } else if (mi.isProc) {
11953                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11954                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11955                pw.println(mi.hasActivities ? ",a" : ",e");
11956            } else {
11957                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11958                pw.println(mi.pss);
11959            }
11960            if (mi.subitems != null) {
11961                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11962                        true, isCompact);
11963            }
11964        }
11965    }
11966
11967    // These are in KB.
11968    static final long[] DUMP_MEM_BUCKETS = new long[] {
11969        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11970        120*1024, 160*1024, 200*1024,
11971        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11972        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11973    };
11974
11975    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11976            boolean stackLike) {
11977        int start = label.lastIndexOf('.');
11978        if (start >= 0) start++;
11979        else start = 0;
11980        int end = label.length();
11981        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11982            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11983                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11984                out.append(bucket);
11985                out.append(stackLike ? "MB." : "MB ");
11986                out.append(label, start, end);
11987                return;
11988            }
11989        }
11990        out.append(memKB/1024);
11991        out.append(stackLike ? "MB." : "MB ");
11992        out.append(label, start, end);
11993    }
11994
11995    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11996            ProcessList.NATIVE_ADJ,
11997            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11998            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11999            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12000            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12001            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12002    };
12003    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12004            "Native",
12005            "System", "Persistent", "Foreground",
12006            "Visible", "Perceptible",
12007            "Heavy Weight", "Backup",
12008            "A Services", "Home",
12009            "Previous", "B Services", "Cached"
12010    };
12011    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12012            "native",
12013            "sys", "pers", "fore",
12014            "vis", "percept",
12015            "heavy", "backup",
12016            "servicea", "home",
12017            "prev", "serviceb", "cached"
12018    };
12019
12020    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12021            long realtime, boolean isCheckinRequest, boolean isCompact) {
12022        if (isCheckinRequest || isCompact) {
12023            // short checkin version
12024            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12025        } else {
12026            pw.println("Applications Memory Usage (kB):");
12027            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12028        }
12029    }
12030
12031    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12032            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12033        boolean dumpDetails = false;
12034        boolean dumpFullDetails = false;
12035        boolean dumpDalvik = false;
12036        boolean oomOnly = false;
12037        boolean isCompact = false;
12038        boolean localOnly = false;
12039
12040        int opti = 0;
12041        while (opti < args.length) {
12042            String opt = args[opti];
12043            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12044                break;
12045            }
12046            opti++;
12047            if ("-a".equals(opt)) {
12048                dumpDetails = true;
12049                dumpFullDetails = true;
12050                dumpDalvik = true;
12051            } else if ("-d".equals(opt)) {
12052                dumpDalvik = true;
12053            } else if ("-c".equals(opt)) {
12054                isCompact = true;
12055            } else if ("--oom".equals(opt)) {
12056                oomOnly = true;
12057            } else if ("--local".equals(opt)) {
12058                localOnly = true;
12059            } else if ("-h".equals(opt)) {
12060                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12061                pw.println("  -a: include all available information for each process.");
12062                pw.println("  -d: include dalvik details when dumping process details.");
12063                pw.println("  -c: dump in a compact machine-parseable representation.");
12064                pw.println("  --oom: only show processes organized by oom adj.");
12065                pw.println("  --local: only collect details locally, don't call process.");
12066                pw.println("If [process] is specified it can be the name or ");
12067                pw.println("pid of a specific process to dump.");
12068                return;
12069            } else {
12070                pw.println("Unknown argument: " + opt + "; use -h for help");
12071            }
12072        }
12073
12074        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12075        long uptime = SystemClock.uptimeMillis();
12076        long realtime = SystemClock.elapsedRealtime();
12077        final long[] tmpLong = new long[1];
12078
12079        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12080        if (procs == null) {
12081            // No Java processes.  Maybe they want to print a native process.
12082            if (args != null && args.length > opti
12083                    && args[opti].charAt(0) != '-') {
12084                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12085                        = new ArrayList<ProcessCpuTracker.Stats>();
12086                updateCpuStatsNow();
12087                int findPid = -1;
12088                try {
12089                    findPid = Integer.parseInt(args[opti]);
12090                } catch (NumberFormatException e) {
12091                }
12092                synchronized (mProcessCpuThread) {
12093                    final int N = mProcessCpuTracker.countStats();
12094                    for (int i=0; i<N; i++) {
12095                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12096                        if (st.pid == findPid || (st.baseName != null
12097                                && st.baseName.equals(args[opti]))) {
12098                            nativeProcs.add(st);
12099                        }
12100                    }
12101                }
12102                if (nativeProcs.size() > 0) {
12103                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12104                            isCompact);
12105                    Debug.MemoryInfo mi = null;
12106                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12107                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12108                        final int pid = r.pid;
12109                        if (!isCheckinRequest && dumpDetails) {
12110                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12111                        }
12112                        if (mi == null) {
12113                            mi = new Debug.MemoryInfo();
12114                        }
12115                        if (dumpDetails || (!brief && !oomOnly)) {
12116                            Debug.getMemoryInfo(pid, mi);
12117                        } else {
12118                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12119                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12120                        }
12121                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12122                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12123                        if (isCheckinRequest) {
12124                            pw.println();
12125                        }
12126                    }
12127                    return;
12128                }
12129            }
12130            pw.println("No process found for: " + args[opti]);
12131            return;
12132        }
12133
12134        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12135            dumpDetails = true;
12136        }
12137
12138        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12139
12140        String[] innerArgs = new String[args.length-opti];
12141        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12142
12143        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12144        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12145        long nativePss=0, dalvikPss=0, otherPss=0;
12146        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12147
12148        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12149        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12150                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12151
12152        long totalPss = 0;
12153        long cachedPss = 0;
12154
12155        Debug.MemoryInfo mi = null;
12156        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12157            final ProcessRecord r = procs.get(i);
12158            final IApplicationThread thread;
12159            final int pid;
12160            final int oomAdj;
12161            final boolean hasActivities;
12162            synchronized (this) {
12163                thread = r.thread;
12164                pid = r.pid;
12165                oomAdj = r.getSetAdjWithServices();
12166                hasActivities = r.activities.size() > 0;
12167            }
12168            if (thread != null) {
12169                if (!isCheckinRequest && dumpDetails) {
12170                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12171                }
12172                if (mi == null) {
12173                    mi = new Debug.MemoryInfo();
12174                }
12175                if (dumpDetails || (!brief && !oomOnly)) {
12176                    Debug.getMemoryInfo(pid, mi);
12177                } else {
12178                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12179                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12180                }
12181                if (dumpDetails) {
12182                    if (localOnly) {
12183                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12184                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12185                        if (isCheckinRequest) {
12186                            pw.println();
12187                        }
12188                    } else {
12189                        try {
12190                            pw.flush();
12191                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12192                                    dumpDalvik, innerArgs);
12193                        } catch (RemoteException e) {
12194                            if (!isCheckinRequest) {
12195                                pw.println("Got RemoteException!");
12196                                pw.flush();
12197                            }
12198                        }
12199                    }
12200                }
12201
12202                final long myTotalPss = mi.getTotalPss();
12203                final long myTotalUss = mi.getTotalUss();
12204
12205                synchronized (this) {
12206                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12207                        // Record this for posterity if the process has been stable.
12208                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12209                    }
12210                }
12211
12212                if (!isCheckinRequest && mi != null) {
12213                    totalPss += myTotalPss;
12214                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12215                            (hasActivities ? " / activities)" : ")"),
12216                            r.processName, myTotalPss, pid, hasActivities);
12217                    procMems.add(pssItem);
12218                    procMemsMap.put(pid, pssItem);
12219
12220                    nativePss += mi.nativePss;
12221                    dalvikPss += mi.dalvikPss;
12222                    otherPss += mi.otherPss;
12223                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12224                        long mem = mi.getOtherPss(j);
12225                        miscPss[j] += mem;
12226                        otherPss -= mem;
12227                    }
12228
12229                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12230                        cachedPss += myTotalPss;
12231                    }
12232
12233                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12234                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12235                                || oomIndex == (oomPss.length-1)) {
12236                            oomPss[oomIndex] += myTotalPss;
12237                            if (oomProcs[oomIndex] == null) {
12238                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12239                            }
12240                            oomProcs[oomIndex].add(pssItem);
12241                            break;
12242                        }
12243                    }
12244                }
12245            }
12246        }
12247
12248        if (!isCheckinRequest && procs.size() > 1) {
12249            // If we are showing aggregations, also look for native processes to
12250            // include so that our aggregations are more accurate.
12251            updateCpuStatsNow();
12252            synchronized (mProcessCpuThread) {
12253                final int N = mProcessCpuTracker.countStats();
12254                for (int i=0; i<N; i++) {
12255                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12256                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12257                        if (mi == null) {
12258                            mi = new Debug.MemoryInfo();
12259                        }
12260                        if (!brief && !oomOnly) {
12261                            Debug.getMemoryInfo(st.pid, mi);
12262                        } else {
12263                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12264                            mi.nativePrivateDirty = (int)tmpLong[0];
12265                        }
12266
12267                        final long myTotalPss = mi.getTotalPss();
12268                        totalPss += myTotalPss;
12269
12270                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12271                                st.name, myTotalPss, st.pid, false);
12272                        procMems.add(pssItem);
12273
12274                        nativePss += mi.nativePss;
12275                        dalvikPss += mi.dalvikPss;
12276                        otherPss += mi.otherPss;
12277                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12278                            long mem = mi.getOtherPss(j);
12279                            miscPss[j] += mem;
12280                            otherPss -= mem;
12281                        }
12282                        oomPss[0] += myTotalPss;
12283                        if (oomProcs[0] == null) {
12284                            oomProcs[0] = new ArrayList<MemItem>();
12285                        }
12286                        oomProcs[0].add(pssItem);
12287                    }
12288                }
12289            }
12290
12291            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12292
12293            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12294            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12295            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12296            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12297                String label = Debug.MemoryInfo.getOtherLabel(j);
12298                catMems.add(new MemItem(label, label, miscPss[j], j));
12299            }
12300
12301            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12302            for (int j=0; j<oomPss.length; j++) {
12303                if (oomPss[j] != 0) {
12304                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12305                            : DUMP_MEM_OOM_LABEL[j];
12306                    MemItem item = new MemItem(label, label, oomPss[j],
12307                            DUMP_MEM_OOM_ADJ[j]);
12308                    item.subitems = oomProcs[j];
12309                    oomMems.add(item);
12310                }
12311            }
12312
12313            if (!brief && !oomOnly && !isCompact) {
12314                pw.println();
12315                pw.println("Total PSS by process:");
12316                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12317                pw.println();
12318            }
12319            if (!isCompact) {
12320                pw.println("Total PSS by OOM adjustment:");
12321            }
12322            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12323            if (!brief && !oomOnly) {
12324                PrintWriter out = categoryPw != null ? categoryPw : pw;
12325                if (!isCompact) {
12326                    out.println();
12327                    out.println("Total PSS by category:");
12328                }
12329                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12330            }
12331            if (!isCompact) {
12332                pw.println();
12333            }
12334            MemInfoReader memInfo = new MemInfoReader();
12335            memInfo.readMemInfo();
12336            if (!brief) {
12337                if (!isCompact) {
12338                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12339                    pw.print(" kB (status ");
12340                    switch (mLastMemoryLevel) {
12341                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12342                            pw.println("normal)");
12343                            break;
12344                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12345                            pw.println("moderate)");
12346                            break;
12347                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12348                            pw.println("low)");
12349                            break;
12350                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12351                            pw.println("critical)");
12352                            break;
12353                        default:
12354                            pw.print(mLastMemoryLevel);
12355                            pw.println(")");
12356                            break;
12357                    }
12358                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12359                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12360                            pw.print(cachedPss); pw.print(" cached pss + ");
12361                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12362                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12363                } else {
12364                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12365                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12366                            + memInfo.getFreeSizeKb()); pw.print(",");
12367                    pw.println(totalPss - cachedPss);
12368                }
12369            }
12370            if (!isCompact) {
12371                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12372                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12373                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12374                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12375                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12376                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12377                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12378                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12379                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12380                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12381                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12382            }
12383            if (!brief) {
12384                if (memInfo.getZramTotalSizeKb() != 0) {
12385                    if (!isCompact) {
12386                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12387                                pw.print(" kB physical used for ");
12388                                pw.print(memInfo.getSwapTotalSizeKb()
12389                                        - memInfo.getSwapFreeSizeKb());
12390                                pw.print(" kB in swap (");
12391                                pw.print(memInfo.getSwapTotalSizeKb());
12392                                pw.println(" kB total swap)");
12393                    } else {
12394                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12395                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12396                                pw.println(memInfo.getSwapFreeSizeKb());
12397                    }
12398                }
12399                final int[] SINGLE_LONG_FORMAT = new int[] {
12400                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12401                };
12402                long[] longOut = new long[1];
12403                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12404                        SINGLE_LONG_FORMAT, null, longOut, null);
12405                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12406                longOut[0] = 0;
12407                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12408                        SINGLE_LONG_FORMAT, null, longOut, null);
12409                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12410                longOut[0] = 0;
12411                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12412                        SINGLE_LONG_FORMAT, null, longOut, null);
12413                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12414                longOut[0] = 0;
12415                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12416                        SINGLE_LONG_FORMAT, null, longOut, null);
12417                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12418                if (!isCompact) {
12419                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12420                        pw.print("      KSM: "); pw.print(sharing);
12421                                pw.print(" kB saved from shared ");
12422                                pw.print(shared); pw.println(" kB");
12423                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12424                                pw.print(voltile); pw.println(" kB volatile");
12425                    }
12426                    pw.print("   Tuning: ");
12427                    pw.print(ActivityManager.staticGetMemoryClass());
12428                    pw.print(" (large ");
12429                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12430                    pw.print("), oom ");
12431                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12432                    pw.print(" kB");
12433                    pw.print(", restore limit ");
12434                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12435                    pw.print(" kB");
12436                    if (ActivityManager.isLowRamDeviceStatic()) {
12437                        pw.print(" (low-ram)");
12438                    }
12439                    if (ActivityManager.isHighEndGfx()) {
12440                        pw.print(" (high-end-gfx)");
12441                    }
12442                    pw.println();
12443                } else {
12444                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12445                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12446                    pw.println(voltile);
12447                    pw.print("tuning,");
12448                    pw.print(ActivityManager.staticGetMemoryClass());
12449                    pw.print(',');
12450                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12451                    pw.print(',');
12452                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12453                    if (ActivityManager.isLowRamDeviceStatic()) {
12454                        pw.print(",low-ram");
12455                    }
12456                    if (ActivityManager.isHighEndGfx()) {
12457                        pw.print(",high-end-gfx");
12458                    }
12459                    pw.println();
12460                }
12461            }
12462        }
12463    }
12464
12465    /**
12466     * Searches array of arguments for the specified string
12467     * @param args array of argument strings
12468     * @param value value to search for
12469     * @return true if the value is contained in the array
12470     */
12471    private static boolean scanArgs(String[] args, String value) {
12472        if (args != null) {
12473            for (String arg : args) {
12474                if (value.equals(arg)) {
12475                    return true;
12476                }
12477            }
12478        }
12479        return false;
12480    }
12481
12482    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12483            ContentProviderRecord cpr, boolean always) {
12484        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12485
12486        if (!inLaunching || always) {
12487            synchronized (cpr) {
12488                cpr.launchingApp = null;
12489                cpr.notifyAll();
12490            }
12491            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12492            String names[] = cpr.info.authority.split(";");
12493            for (int j = 0; j < names.length; j++) {
12494                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12495            }
12496        }
12497
12498        for (int i=0; i<cpr.connections.size(); i++) {
12499            ContentProviderConnection conn = cpr.connections.get(i);
12500            if (conn.waiting) {
12501                // If this connection is waiting for the provider, then we don't
12502                // need to mess with its process unless we are always removing
12503                // or for some reason the provider is not currently launching.
12504                if (inLaunching && !always) {
12505                    continue;
12506                }
12507            }
12508            ProcessRecord capp = conn.client;
12509            conn.dead = true;
12510            if (conn.stableCount > 0) {
12511                if (!capp.persistent && capp.thread != null
12512                        && capp.pid != 0
12513                        && capp.pid != MY_PID) {
12514                    killUnneededProcessLocked(capp, "depends on provider "
12515                            + cpr.name.flattenToShortString()
12516                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12517                }
12518            } else if (capp.thread != null && conn.provider.provider != null) {
12519                try {
12520                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12521                } catch (RemoteException e) {
12522                }
12523                // In the protocol here, we don't expect the client to correctly
12524                // clean up this connection, we'll just remove it.
12525                cpr.connections.remove(i);
12526                conn.client.conProviders.remove(conn);
12527            }
12528        }
12529
12530        if (inLaunching && always) {
12531            mLaunchingProviders.remove(cpr);
12532        }
12533        return inLaunching;
12534    }
12535
12536    /**
12537     * Main code for cleaning up a process when it has gone away.  This is
12538     * called both as a result of the process dying, or directly when stopping
12539     * a process when running in single process mode.
12540     */
12541    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12542            boolean restarting, boolean allowRestart, int index) {
12543        if (index >= 0) {
12544            removeLruProcessLocked(app);
12545            ProcessList.remove(app.pid);
12546        }
12547
12548        mProcessesToGc.remove(app);
12549        mPendingPssProcesses.remove(app);
12550
12551        // Dismiss any open dialogs.
12552        if (app.crashDialog != null && !app.forceCrashReport) {
12553            app.crashDialog.dismiss();
12554            app.crashDialog = null;
12555        }
12556        if (app.anrDialog != null) {
12557            app.anrDialog.dismiss();
12558            app.anrDialog = null;
12559        }
12560        if (app.waitDialog != null) {
12561            app.waitDialog.dismiss();
12562            app.waitDialog = null;
12563        }
12564
12565        app.crashing = false;
12566        app.notResponding = false;
12567
12568        app.resetPackageList(mProcessStats);
12569        app.unlinkDeathRecipient();
12570        app.makeInactive(mProcessStats);
12571        app.forcingToForeground = null;
12572        updateProcessForegroundLocked(app, false, false);
12573        app.foregroundActivities = false;
12574        app.hasShownUi = false;
12575        app.treatLikeActivity = false;
12576        app.hasAboveClient = false;
12577        app.hasClientActivities = false;
12578
12579        mServices.killServicesLocked(app, allowRestart);
12580
12581        boolean restart = false;
12582
12583        // Remove published content providers.
12584        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12585            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12586            final boolean always = app.bad || !allowRestart;
12587            if (removeDyingProviderLocked(app, cpr, always) || always) {
12588                // We left the provider in the launching list, need to
12589                // restart it.
12590                restart = true;
12591            }
12592
12593            cpr.provider = null;
12594            cpr.proc = null;
12595        }
12596        app.pubProviders.clear();
12597
12598        // Take care of any launching providers waiting for this process.
12599        if (checkAppInLaunchingProvidersLocked(app, false)) {
12600            restart = true;
12601        }
12602
12603        // Unregister from connected content providers.
12604        if (!app.conProviders.isEmpty()) {
12605            for (int i=0; i<app.conProviders.size(); i++) {
12606                ContentProviderConnection conn = app.conProviders.get(i);
12607                conn.provider.connections.remove(conn);
12608            }
12609            app.conProviders.clear();
12610        }
12611
12612        // At this point there may be remaining entries in mLaunchingProviders
12613        // where we were the only one waiting, so they are no longer of use.
12614        // Look for these and clean up if found.
12615        // XXX Commented out for now.  Trying to figure out a way to reproduce
12616        // the actual situation to identify what is actually going on.
12617        if (false) {
12618            for (int i=0; i<mLaunchingProviders.size(); i++) {
12619                ContentProviderRecord cpr = (ContentProviderRecord)
12620                        mLaunchingProviders.get(i);
12621                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12622                    synchronized (cpr) {
12623                        cpr.launchingApp = null;
12624                        cpr.notifyAll();
12625                    }
12626                }
12627            }
12628        }
12629
12630        skipCurrentReceiverLocked(app);
12631
12632        // Unregister any receivers.
12633        for (int i=app.receivers.size()-1; i>=0; i--) {
12634            removeReceiverLocked(app.receivers.valueAt(i));
12635        }
12636        app.receivers.clear();
12637
12638        // If the app is undergoing backup, tell the backup manager about it
12639        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12640            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12641                    + mBackupTarget.appInfo + " died during backup");
12642            try {
12643                IBackupManager bm = IBackupManager.Stub.asInterface(
12644                        ServiceManager.getService(Context.BACKUP_SERVICE));
12645                bm.agentDisconnected(app.info.packageName);
12646            } catch (RemoteException e) {
12647                // can't happen; backup manager is local
12648            }
12649        }
12650
12651        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12652            ProcessChangeItem item = mPendingProcessChanges.get(i);
12653            if (item.pid == app.pid) {
12654                mPendingProcessChanges.remove(i);
12655                mAvailProcessChanges.add(item);
12656            }
12657        }
12658        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12659
12660        // If the caller is restarting this app, then leave it in its
12661        // current lists and let the caller take care of it.
12662        if (restarting) {
12663            return;
12664        }
12665
12666        if (!app.persistent || app.isolated) {
12667            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12668                    "Removing non-persistent process during cleanup: " + app);
12669            mProcessNames.remove(app.processName, app.uid);
12670            mIsolatedProcesses.remove(app.uid);
12671            if (mHeavyWeightProcess == app) {
12672                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12673                        mHeavyWeightProcess.userId, 0));
12674                mHeavyWeightProcess = null;
12675            }
12676        } else if (!app.removed) {
12677            // This app is persistent, so we need to keep its record around.
12678            // If it is not already on the pending app list, add it there
12679            // and start a new process for it.
12680            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12681                mPersistentStartingProcesses.add(app);
12682                restart = true;
12683            }
12684        }
12685        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12686                "Clean-up removing on hold: " + app);
12687        mProcessesOnHold.remove(app);
12688
12689        if (app == mHomeProcess) {
12690            mHomeProcess = null;
12691        }
12692        if (app == mPreviousProcess) {
12693            mPreviousProcess = null;
12694        }
12695
12696        if (restart && !app.isolated) {
12697            // We have components that still need to be running in the
12698            // process, so re-launch it.
12699            mProcessNames.put(app.processName, app.uid, app);
12700            startProcessLocked(app, "restart", app.processName);
12701        } else if (app.pid > 0 && app.pid != MY_PID) {
12702            // Goodbye!
12703            boolean removed;
12704            synchronized (mPidsSelfLocked) {
12705                mPidsSelfLocked.remove(app.pid);
12706                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12707            }
12708            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12709                    app.processName, app.info.uid);
12710            if (app.isolated) {
12711                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12712            }
12713            app.setPid(0);
12714        }
12715    }
12716
12717    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12718        // Look through the content providers we are waiting to have launched,
12719        // and if any run in this process then either schedule a restart of
12720        // the process or kill the client waiting for it if this process has
12721        // gone bad.
12722        int NL = mLaunchingProviders.size();
12723        boolean restart = false;
12724        for (int i=0; i<NL; i++) {
12725            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12726            if (cpr.launchingApp == app) {
12727                if (!alwaysBad && !app.bad) {
12728                    restart = true;
12729                } else {
12730                    removeDyingProviderLocked(app, cpr, true);
12731                    // cpr should have been removed from mLaunchingProviders
12732                    NL = mLaunchingProviders.size();
12733                    i--;
12734                }
12735            }
12736        }
12737        return restart;
12738    }
12739
12740    // =========================================================
12741    // SERVICES
12742    // =========================================================
12743
12744    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12745            int flags) {
12746        enforceNotIsolatedCaller("getServices");
12747        synchronized (this) {
12748            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12749        }
12750    }
12751
12752    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12753        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12754        synchronized (this) {
12755            return mServices.getRunningServiceControlPanelLocked(name);
12756        }
12757    }
12758
12759    public ComponentName startService(IApplicationThread caller, Intent service,
12760            String resolvedType, int userId) {
12761        enforceNotIsolatedCaller("startService");
12762        // Refuse possible leaked file descriptors
12763        if (service != null && service.hasFileDescriptors() == true) {
12764            throw new IllegalArgumentException("File descriptors passed in Intent");
12765        }
12766
12767        if (DEBUG_SERVICE)
12768            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12769        synchronized(this) {
12770            final int callingPid = Binder.getCallingPid();
12771            final int callingUid = Binder.getCallingUid();
12772            final long origId = Binder.clearCallingIdentity();
12773            ComponentName res = mServices.startServiceLocked(caller, service,
12774                    resolvedType, callingPid, callingUid, userId);
12775            Binder.restoreCallingIdentity(origId);
12776            return res;
12777        }
12778    }
12779
12780    ComponentName startServiceInPackage(int uid,
12781            Intent service, String resolvedType, int userId) {
12782        synchronized(this) {
12783            if (DEBUG_SERVICE)
12784                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12785            final long origId = Binder.clearCallingIdentity();
12786            ComponentName res = mServices.startServiceLocked(null, service,
12787                    resolvedType, -1, uid, userId);
12788            Binder.restoreCallingIdentity(origId);
12789            return res;
12790        }
12791    }
12792
12793    public int stopService(IApplicationThread caller, Intent service,
12794            String resolvedType, int userId) {
12795        enforceNotIsolatedCaller("stopService");
12796        // Refuse possible leaked file descriptors
12797        if (service != null && service.hasFileDescriptors() == true) {
12798            throw new IllegalArgumentException("File descriptors passed in Intent");
12799        }
12800
12801        synchronized(this) {
12802            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12803        }
12804    }
12805
12806    public IBinder peekService(Intent service, String resolvedType) {
12807        enforceNotIsolatedCaller("peekService");
12808        // Refuse possible leaked file descriptors
12809        if (service != null && service.hasFileDescriptors() == true) {
12810            throw new IllegalArgumentException("File descriptors passed in Intent");
12811        }
12812        synchronized(this) {
12813            return mServices.peekServiceLocked(service, resolvedType);
12814        }
12815    }
12816
12817    public boolean stopServiceToken(ComponentName className, IBinder token,
12818            int startId) {
12819        synchronized(this) {
12820            return mServices.stopServiceTokenLocked(className, token, startId);
12821        }
12822    }
12823
12824    public void setServiceForeground(ComponentName className, IBinder token,
12825            int id, Notification notification, boolean removeNotification) {
12826        synchronized(this) {
12827            mServices.setServiceForegroundLocked(className, token, id, notification,
12828                    removeNotification);
12829        }
12830    }
12831
12832    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12833            boolean requireFull, String name, String callerPackage) {
12834        final int callingUserId = UserHandle.getUserId(callingUid);
12835        if (callingUserId != userId) {
12836            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12837                if ((requireFull || checkComponentPermission(
12838                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12839                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12840                        && checkComponentPermission(
12841                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12842                                callingPid, callingUid, -1, true)
12843                                != PackageManager.PERMISSION_GRANTED) {
12844                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12845                        // In this case, they would like to just execute as their
12846                        // owner user instead of failing.
12847                        userId = callingUserId;
12848                    } else {
12849                        StringBuilder builder = new StringBuilder(128);
12850                        builder.append("Permission Denial: ");
12851                        builder.append(name);
12852                        if (callerPackage != null) {
12853                            builder.append(" from ");
12854                            builder.append(callerPackage);
12855                        }
12856                        builder.append(" asks to run as user ");
12857                        builder.append(userId);
12858                        builder.append(" but is calling from user ");
12859                        builder.append(UserHandle.getUserId(callingUid));
12860                        builder.append("; this requires ");
12861                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12862                        if (!requireFull) {
12863                            builder.append(" or ");
12864                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12865                        }
12866                        String msg = builder.toString();
12867                        Slog.w(TAG, msg);
12868                        throw new SecurityException(msg);
12869                    }
12870                }
12871            }
12872            if (userId == UserHandle.USER_CURRENT
12873                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12874                // Note that we may be accessing this outside of a lock...
12875                // shouldn't be a big deal, if this is being called outside
12876                // of a locked context there is intrinsically a race with
12877                // the value the caller will receive and someone else changing it.
12878                userId = mCurrentUserId;
12879            }
12880            if (!allowAll && userId < 0) {
12881                throw new IllegalArgumentException(
12882                        "Call does not support special user #" + userId);
12883            }
12884        }
12885        return userId;
12886    }
12887
12888    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12889            String className, int flags) {
12890        boolean result = false;
12891        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12892            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12893                if (ActivityManager.checkUidPermission(
12894                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12895                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12896                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12897                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12898                            + " requests FLAG_SINGLE_USER, but app does not hold "
12899                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12900                    Slog.w(TAG, msg);
12901                    throw new SecurityException(msg);
12902                }
12903                result = true;
12904            }
12905        } else if (componentProcessName == aInfo.packageName) {
12906            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12907        } else if ("system".equals(componentProcessName)) {
12908            result = true;
12909        }
12910        if (DEBUG_MU) {
12911            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12912                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12913        }
12914        return result;
12915    }
12916
12917    public int bindService(IApplicationThread caller, IBinder token,
12918            Intent service, String resolvedType,
12919            IServiceConnection connection, int flags, int userId) {
12920        enforceNotIsolatedCaller("bindService");
12921        // Refuse possible leaked file descriptors
12922        if (service != null && service.hasFileDescriptors() == true) {
12923            throw new IllegalArgumentException("File descriptors passed in Intent");
12924        }
12925
12926        synchronized(this) {
12927            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12928                    connection, flags, userId);
12929        }
12930    }
12931
12932    public boolean unbindService(IServiceConnection connection) {
12933        synchronized (this) {
12934            return mServices.unbindServiceLocked(connection);
12935        }
12936    }
12937
12938    public void publishService(IBinder token, Intent intent, IBinder service) {
12939        // Refuse possible leaked file descriptors
12940        if (intent != null && intent.hasFileDescriptors() == true) {
12941            throw new IllegalArgumentException("File descriptors passed in Intent");
12942        }
12943
12944        synchronized(this) {
12945            if (!(token instanceof ServiceRecord)) {
12946                throw new IllegalArgumentException("Invalid service token");
12947            }
12948            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12949        }
12950    }
12951
12952    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12953        // Refuse possible leaked file descriptors
12954        if (intent != null && intent.hasFileDescriptors() == true) {
12955            throw new IllegalArgumentException("File descriptors passed in Intent");
12956        }
12957
12958        synchronized(this) {
12959            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12960        }
12961    }
12962
12963    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12964        synchronized(this) {
12965            if (!(token instanceof ServiceRecord)) {
12966                throw new IllegalArgumentException("Invalid service token");
12967            }
12968            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12969        }
12970    }
12971
12972    // =========================================================
12973    // BACKUP AND RESTORE
12974    // =========================================================
12975
12976    // Cause the target app to be launched if necessary and its backup agent
12977    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12978    // activity manager to announce its creation.
12979    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12980        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12981        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12982
12983        synchronized(this) {
12984            // !!! TODO: currently no check here that we're already bound
12985            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12986            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12987            synchronized (stats) {
12988                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12989            }
12990
12991            // Backup agent is now in use, its package can't be stopped.
12992            try {
12993                AppGlobals.getPackageManager().setPackageStoppedState(
12994                        app.packageName, false, UserHandle.getUserId(app.uid));
12995            } catch (RemoteException e) {
12996            } catch (IllegalArgumentException e) {
12997                Slog.w(TAG, "Failed trying to unstop package "
12998                        + app.packageName + ": " + e);
12999            }
13000
13001            BackupRecord r = new BackupRecord(ss, app, backupMode);
13002            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13003                    ? new ComponentName(app.packageName, app.backupAgentName)
13004                    : new ComponentName("android", "FullBackupAgent");
13005            // startProcessLocked() returns existing proc's record if it's already running
13006            ProcessRecord proc = startProcessLocked(app.processName, app,
13007                    false, 0, "backup", hostingName, false, false, false);
13008            if (proc == null) {
13009                Slog.e(TAG, "Unable to start backup agent process " + r);
13010                return false;
13011            }
13012
13013            r.app = proc;
13014            mBackupTarget = r;
13015            mBackupAppName = app.packageName;
13016
13017            // Try not to kill the process during backup
13018            updateOomAdjLocked(proc);
13019
13020            // If the process is already attached, schedule the creation of the backup agent now.
13021            // If it is not yet live, this will be done when it attaches to the framework.
13022            if (proc.thread != null) {
13023                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13024                try {
13025                    proc.thread.scheduleCreateBackupAgent(app,
13026                            compatibilityInfoForPackageLocked(app), backupMode);
13027                } catch (RemoteException e) {
13028                    // Will time out on the backup manager side
13029                }
13030            } else {
13031                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13032            }
13033            // Invariants: at this point, the target app process exists and the application
13034            // is either already running or in the process of coming up.  mBackupTarget and
13035            // mBackupAppName describe the app, so that when it binds back to the AM we
13036            // know that it's scheduled for a backup-agent operation.
13037        }
13038
13039        return true;
13040    }
13041
13042    @Override
13043    public void clearPendingBackup() {
13044        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13045        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13046
13047        synchronized (this) {
13048            mBackupTarget = null;
13049            mBackupAppName = null;
13050        }
13051    }
13052
13053    // A backup agent has just come up
13054    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13055        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13056                + " = " + agent);
13057
13058        synchronized(this) {
13059            if (!agentPackageName.equals(mBackupAppName)) {
13060                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13061                return;
13062            }
13063        }
13064
13065        long oldIdent = Binder.clearCallingIdentity();
13066        try {
13067            IBackupManager bm = IBackupManager.Stub.asInterface(
13068                    ServiceManager.getService(Context.BACKUP_SERVICE));
13069            bm.agentConnected(agentPackageName, agent);
13070        } catch (RemoteException e) {
13071            // can't happen; the backup manager service is local
13072        } catch (Exception e) {
13073            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13074            e.printStackTrace();
13075        } finally {
13076            Binder.restoreCallingIdentity(oldIdent);
13077        }
13078    }
13079
13080    // done with this agent
13081    public void unbindBackupAgent(ApplicationInfo appInfo) {
13082        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13083        if (appInfo == null) {
13084            Slog.w(TAG, "unbind backup agent for null app");
13085            return;
13086        }
13087
13088        synchronized(this) {
13089            try {
13090                if (mBackupAppName == null) {
13091                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13092                    return;
13093                }
13094
13095                if (!mBackupAppName.equals(appInfo.packageName)) {
13096                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13097                    return;
13098                }
13099
13100                // Not backing this app up any more; reset its OOM adjustment
13101                final ProcessRecord proc = mBackupTarget.app;
13102                updateOomAdjLocked(proc);
13103
13104                // If the app crashed during backup, 'thread' will be null here
13105                if (proc.thread != null) {
13106                    try {
13107                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13108                                compatibilityInfoForPackageLocked(appInfo));
13109                    } catch (Exception e) {
13110                        Slog.e(TAG, "Exception when unbinding backup agent:");
13111                        e.printStackTrace();
13112                    }
13113                }
13114            } finally {
13115                mBackupTarget = null;
13116                mBackupAppName = null;
13117            }
13118        }
13119    }
13120    // =========================================================
13121    // BROADCASTS
13122    // =========================================================
13123
13124    private final List getStickiesLocked(String action, IntentFilter filter,
13125            List cur, int userId) {
13126        final ContentResolver resolver = mContext.getContentResolver();
13127        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13128        if (stickies == null) {
13129            return cur;
13130        }
13131        final ArrayList<Intent> list = stickies.get(action);
13132        if (list == null) {
13133            return cur;
13134        }
13135        int N = list.size();
13136        for (int i=0; i<N; i++) {
13137            Intent intent = list.get(i);
13138            if (filter.match(resolver, intent, true, TAG) >= 0) {
13139                if (cur == null) {
13140                    cur = new ArrayList<Intent>();
13141                }
13142                cur.add(intent);
13143            }
13144        }
13145        return cur;
13146    }
13147
13148    boolean isPendingBroadcastProcessLocked(int pid) {
13149        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13150                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13151    }
13152
13153    void skipPendingBroadcastLocked(int pid) {
13154            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13155            for (BroadcastQueue queue : mBroadcastQueues) {
13156                queue.skipPendingBroadcastLocked(pid);
13157            }
13158    }
13159
13160    // The app just attached; send any pending broadcasts that it should receive
13161    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13162        boolean didSomething = false;
13163        for (BroadcastQueue queue : mBroadcastQueues) {
13164            didSomething |= queue.sendPendingBroadcastsLocked(app);
13165        }
13166        return didSomething;
13167    }
13168
13169    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13170            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13171        enforceNotIsolatedCaller("registerReceiver");
13172        int callingUid;
13173        int callingPid;
13174        synchronized(this) {
13175            ProcessRecord callerApp = null;
13176            if (caller != null) {
13177                callerApp = getRecordForAppLocked(caller);
13178                if (callerApp == null) {
13179                    throw new SecurityException(
13180                            "Unable to find app for caller " + caller
13181                            + " (pid=" + Binder.getCallingPid()
13182                            + ") when registering receiver " + receiver);
13183                }
13184                if (callerApp.info.uid != Process.SYSTEM_UID &&
13185                        !callerApp.pkgList.containsKey(callerPackage) &&
13186                        !"android".equals(callerPackage)) {
13187                    throw new SecurityException("Given caller package " + callerPackage
13188                            + " is not running in process " + callerApp);
13189                }
13190                callingUid = callerApp.info.uid;
13191                callingPid = callerApp.pid;
13192            } else {
13193                callerPackage = null;
13194                callingUid = Binder.getCallingUid();
13195                callingPid = Binder.getCallingPid();
13196            }
13197
13198            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13199                    true, true, "registerReceiver", callerPackage);
13200
13201            List allSticky = null;
13202
13203            // Look for any matching sticky broadcasts...
13204            Iterator actions = filter.actionsIterator();
13205            if (actions != null) {
13206                while (actions.hasNext()) {
13207                    String action = (String)actions.next();
13208                    allSticky = getStickiesLocked(action, filter, allSticky,
13209                            UserHandle.USER_ALL);
13210                    allSticky = getStickiesLocked(action, filter, allSticky,
13211                            UserHandle.getUserId(callingUid));
13212                }
13213            } else {
13214                allSticky = getStickiesLocked(null, filter, allSticky,
13215                        UserHandle.USER_ALL);
13216                allSticky = getStickiesLocked(null, filter, allSticky,
13217                        UserHandle.getUserId(callingUid));
13218            }
13219
13220            // The first sticky in the list is returned directly back to
13221            // the client.
13222            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13223
13224            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13225                    + ": " + sticky);
13226
13227            if (receiver == null) {
13228                return sticky;
13229            }
13230
13231            ReceiverList rl
13232                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13233            if (rl == null) {
13234                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13235                        userId, receiver);
13236                if (rl.app != null) {
13237                    rl.app.receivers.add(rl);
13238                } else {
13239                    try {
13240                        receiver.asBinder().linkToDeath(rl, 0);
13241                    } catch (RemoteException e) {
13242                        return sticky;
13243                    }
13244                    rl.linkedToDeath = true;
13245                }
13246                mRegisteredReceivers.put(receiver.asBinder(), rl);
13247            } else if (rl.uid != callingUid) {
13248                throw new IllegalArgumentException(
13249                        "Receiver requested to register for uid " + callingUid
13250                        + " was previously registered for uid " + rl.uid);
13251            } else if (rl.pid != callingPid) {
13252                throw new IllegalArgumentException(
13253                        "Receiver requested to register for pid " + callingPid
13254                        + " was previously registered for pid " + rl.pid);
13255            } else if (rl.userId != userId) {
13256                throw new IllegalArgumentException(
13257                        "Receiver requested to register for user " + userId
13258                        + " was previously registered for user " + rl.userId);
13259            }
13260            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13261                    permission, callingUid, userId);
13262            rl.add(bf);
13263            if (!bf.debugCheck()) {
13264                Slog.w(TAG, "==> For Dynamic broadast");
13265            }
13266            mReceiverResolver.addFilter(bf);
13267
13268            // Enqueue broadcasts for all existing stickies that match
13269            // this filter.
13270            if (allSticky != null) {
13271                ArrayList receivers = new ArrayList();
13272                receivers.add(bf);
13273
13274                int N = allSticky.size();
13275                for (int i=0; i<N; i++) {
13276                    Intent intent = (Intent)allSticky.get(i);
13277                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13278                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13279                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13280                            null, null, false, true, true, -1);
13281                    queue.enqueueParallelBroadcastLocked(r);
13282                    queue.scheduleBroadcastsLocked();
13283                }
13284            }
13285
13286            return sticky;
13287        }
13288    }
13289
13290    public void unregisterReceiver(IIntentReceiver receiver) {
13291        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13292
13293        final long origId = Binder.clearCallingIdentity();
13294        try {
13295            boolean doTrim = false;
13296
13297            synchronized(this) {
13298                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13299                if (rl != null) {
13300                    if (rl.curBroadcast != null) {
13301                        BroadcastRecord r = rl.curBroadcast;
13302                        final boolean doNext = finishReceiverLocked(
13303                                receiver.asBinder(), r.resultCode, r.resultData,
13304                                r.resultExtras, r.resultAbort);
13305                        if (doNext) {
13306                            doTrim = true;
13307                            r.queue.processNextBroadcast(false);
13308                        }
13309                    }
13310
13311                    if (rl.app != null) {
13312                        rl.app.receivers.remove(rl);
13313                    }
13314                    removeReceiverLocked(rl);
13315                    if (rl.linkedToDeath) {
13316                        rl.linkedToDeath = false;
13317                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13318                    }
13319                }
13320            }
13321
13322            // If we actually concluded any broadcasts, we might now be able
13323            // to trim the recipients' apps from our working set
13324            if (doTrim) {
13325                trimApplications();
13326                return;
13327            }
13328
13329        } finally {
13330            Binder.restoreCallingIdentity(origId);
13331        }
13332    }
13333
13334    void removeReceiverLocked(ReceiverList rl) {
13335        mRegisteredReceivers.remove(rl.receiver.asBinder());
13336        int N = rl.size();
13337        for (int i=0; i<N; i++) {
13338            mReceiverResolver.removeFilter(rl.get(i));
13339        }
13340    }
13341
13342    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13343        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13344            ProcessRecord r = mLruProcesses.get(i);
13345            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13346                try {
13347                    r.thread.dispatchPackageBroadcast(cmd, packages);
13348                } catch (RemoteException ex) {
13349                }
13350            }
13351        }
13352    }
13353
13354    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13355            int[] users) {
13356        List<ResolveInfo> receivers = null;
13357        try {
13358            HashSet<ComponentName> singleUserReceivers = null;
13359            boolean scannedFirstReceivers = false;
13360            for (int user : users) {
13361                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13362                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13363                if (user != 0 && newReceivers != null) {
13364                    // If this is not the primary user, we need to check for
13365                    // any receivers that should be filtered out.
13366                    for (int i=0; i<newReceivers.size(); i++) {
13367                        ResolveInfo ri = newReceivers.get(i);
13368                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13369                            newReceivers.remove(i);
13370                            i--;
13371                        }
13372                    }
13373                }
13374                if (newReceivers != null && newReceivers.size() == 0) {
13375                    newReceivers = null;
13376                }
13377                if (receivers == null) {
13378                    receivers = newReceivers;
13379                } else if (newReceivers != null) {
13380                    // We need to concatenate the additional receivers
13381                    // found with what we have do far.  This would be easy,
13382                    // but we also need to de-dup any receivers that are
13383                    // singleUser.
13384                    if (!scannedFirstReceivers) {
13385                        // Collect any single user receivers we had already retrieved.
13386                        scannedFirstReceivers = true;
13387                        for (int i=0; i<receivers.size(); i++) {
13388                            ResolveInfo ri = receivers.get(i);
13389                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13390                                ComponentName cn = new ComponentName(
13391                                        ri.activityInfo.packageName, ri.activityInfo.name);
13392                                if (singleUserReceivers == null) {
13393                                    singleUserReceivers = new HashSet<ComponentName>();
13394                                }
13395                                singleUserReceivers.add(cn);
13396                            }
13397                        }
13398                    }
13399                    // Add the new results to the existing results, tracking
13400                    // and de-dupping single user receivers.
13401                    for (int i=0; i<newReceivers.size(); i++) {
13402                        ResolveInfo ri = newReceivers.get(i);
13403                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13404                            ComponentName cn = new ComponentName(
13405                                    ri.activityInfo.packageName, ri.activityInfo.name);
13406                            if (singleUserReceivers == null) {
13407                                singleUserReceivers = new HashSet<ComponentName>();
13408                            }
13409                            if (!singleUserReceivers.contains(cn)) {
13410                                singleUserReceivers.add(cn);
13411                                receivers.add(ri);
13412                            }
13413                        } else {
13414                            receivers.add(ri);
13415                        }
13416                    }
13417                }
13418            }
13419        } catch (RemoteException ex) {
13420            // pm is in same process, this will never happen.
13421        }
13422        return receivers;
13423    }
13424
13425    private final int broadcastIntentLocked(ProcessRecord callerApp,
13426            String callerPackage, Intent intent, String resolvedType,
13427            IIntentReceiver resultTo, int resultCode, String resultData,
13428            Bundle map, String requiredPermission, int appOp,
13429            boolean ordered, boolean sticky, int callingPid, int callingUid,
13430            int userId) {
13431        intent = new Intent(intent);
13432
13433        // By default broadcasts do not go to stopped apps.
13434        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13435
13436        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13437            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13438            + " ordered=" + ordered + " userid=" + userId);
13439        if ((resultTo != null) && !ordered) {
13440            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13441        }
13442
13443        userId = handleIncomingUser(callingPid, callingUid, userId,
13444                true, false, "broadcast", callerPackage);
13445
13446        // Make sure that the user who is receiving this broadcast is started.
13447        // If not, we will just skip it.
13448        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13449            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13450                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13451                Slog.w(TAG, "Skipping broadcast of " + intent
13452                        + ": user " + userId + " is stopped");
13453                return ActivityManager.BROADCAST_SUCCESS;
13454            }
13455        }
13456
13457        /*
13458         * Prevent non-system code (defined here to be non-persistent
13459         * processes) from sending protected broadcasts.
13460         */
13461        int callingAppId = UserHandle.getAppId(callingUid);
13462        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13463            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13464            callingUid == 0) {
13465            // Always okay.
13466        } else if (callerApp == null || !callerApp.persistent) {
13467            try {
13468                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13469                        intent.getAction())) {
13470                    String msg = "Permission Denial: not allowed to send broadcast "
13471                            + intent.getAction() + " from pid="
13472                            + callingPid + ", uid=" + callingUid;
13473                    Slog.w(TAG, msg);
13474                    throw new SecurityException(msg);
13475                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13476                    // Special case for compatibility: we don't want apps to send this,
13477                    // but historically it has not been protected and apps may be using it
13478                    // to poke their own app widget.  So, instead of making it protected,
13479                    // just limit it to the caller.
13480                    if (callerApp == null) {
13481                        String msg = "Permission Denial: not allowed to send broadcast "
13482                                + intent.getAction() + " from unknown caller.";
13483                        Slog.w(TAG, msg);
13484                        throw new SecurityException(msg);
13485                    } else if (intent.getComponent() != null) {
13486                        // They are good enough to send to an explicit component...  verify
13487                        // it is being sent to the calling app.
13488                        if (!intent.getComponent().getPackageName().equals(
13489                                callerApp.info.packageName)) {
13490                            String msg = "Permission Denial: not allowed to send broadcast "
13491                                    + intent.getAction() + " to "
13492                                    + intent.getComponent().getPackageName() + " from "
13493                                    + callerApp.info.packageName;
13494                            Slog.w(TAG, msg);
13495                            throw new SecurityException(msg);
13496                        }
13497                    } else {
13498                        // Limit broadcast to their own package.
13499                        intent.setPackage(callerApp.info.packageName);
13500                    }
13501                }
13502            } catch (RemoteException e) {
13503                Slog.w(TAG, "Remote exception", e);
13504                return ActivityManager.BROADCAST_SUCCESS;
13505            }
13506        }
13507
13508        // Handle special intents: if this broadcast is from the package
13509        // manager about a package being removed, we need to remove all of
13510        // its activities from the history stack.
13511        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13512                intent.getAction());
13513        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13514                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13515                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13516                || uidRemoved) {
13517            if (checkComponentPermission(
13518                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13519                    callingPid, callingUid, -1, true)
13520                    == PackageManager.PERMISSION_GRANTED) {
13521                if (uidRemoved) {
13522                    final Bundle intentExtras = intent.getExtras();
13523                    final int uid = intentExtras != null
13524                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13525                    if (uid >= 0) {
13526                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13527                        synchronized (bs) {
13528                            bs.removeUidStatsLocked(uid);
13529                        }
13530                        mAppOpsService.uidRemoved(uid);
13531                    }
13532                } else {
13533                    // If resources are unavailable just force stop all
13534                    // those packages and flush the attribute cache as well.
13535                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13536                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13537                        if (list != null && (list.length > 0)) {
13538                            for (String pkg : list) {
13539                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13540                                        "storage unmount");
13541                            }
13542                            sendPackageBroadcastLocked(
13543                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13544                        }
13545                    } else {
13546                        Uri data = intent.getData();
13547                        String ssp;
13548                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13549                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13550                                    intent.getAction());
13551                            boolean fullUninstall = removed &&
13552                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13553                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13554                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13555                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13556                                        false, fullUninstall, userId,
13557                                        removed ? "pkg removed" : "pkg changed");
13558                            }
13559                            if (removed) {
13560                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13561                                        new String[] {ssp}, userId);
13562                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13563                                    mAppOpsService.packageRemoved(
13564                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13565
13566                                    // Remove all permissions granted from/to this package
13567                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13568                                }
13569                            }
13570                        }
13571                    }
13572                }
13573            } else {
13574                String msg = "Permission Denial: " + intent.getAction()
13575                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13576                        + ", uid=" + callingUid + ")"
13577                        + " requires "
13578                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13579                Slog.w(TAG, msg);
13580                throw new SecurityException(msg);
13581            }
13582
13583        // Special case for adding a package: by default turn on compatibility
13584        // mode.
13585        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13586            Uri data = intent.getData();
13587            String ssp;
13588            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13589                mCompatModePackages.handlePackageAddedLocked(ssp,
13590                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13591            }
13592        }
13593
13594        /*
13595         * If this is the time zone changed action, queue up a message that will reset the timezone
13596         * of all currently running processes. This message will get queued up before the broadcast
13597         * happens.
13598         */
13599        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13600            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13601        }
13602
13603        /*
13604         * If the user set the time, let all running processes know.
13605         */
13606        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13607            final int is24Hour = intent.getBooleanExtra(
13608                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13609            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13610        }
13611
13612        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13613            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13614        }
13615
13616        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13617            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13618            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13619        }
13620
13621        // Add to the sticky list if requested.
13622        if (sticky) {
13623            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13624                    callingPid, callingUid)
13625                    != PackageManager.PERMISSION_GRANTED) {
13626                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13627                        + callingPid + ", uid=" + callingUid
13628                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13629                Slog.w(TAG, msg);
13630                throw new SecurityException(msg);
13631            }
13632            if (requiredPermission != null) {
13633                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13634                        + " and enforce permission " + requiredPermission);
13635                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13636            }
13637            if (intent.getComponent() != null) {
13638                throw new SecurityException(
13639                        "Sticky broadcasts can't target a specific component");
13640            }
13641            // We use userId directly here, since the "all" target is maintained
13642            // as a separate set of sticky broadcasts.
13643            if (userId != UserHandle.USER_ALL) {
13644                // But first, if this is not a broadcast to all users, then
13645                // make sure it doesn't conflict with an existing broadcast to
13646                // all users.
13647                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13648                        UserHandle.USER_ALL);
13649                if (stickies != null) {
13650                    ArrayList<Intent> list = stickies.get(intent.getAction());
13651                    if (list != null) {
13652                        int N = list.size();
13653                        int i;
13654                        for (i=0; i<N; i++) {
13655                            if (intent.filterEquals(list.get(i))) {
13656                                throw new IllegalArgumentException(
13657                                        "Sticky broadcast " + intent + " for user "
13658                                        + userId + " conflicts with existing global broadcast");
13659                            }
13660                        }
13661                    }
13662                }
13663            }
13664            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13665            if (stickies == null) {
13666                stickies = new ArrayMap<String, ArrayList<Intent>>();
13667                mStickyBroadcasts.put(userId, stickies);
13668            }
13669            ArrayList<Intent> list = stickies.get(intent.getAction());
13670            if (list == null) {
13671                list = new ArrayList<Intent>();
13672                stickies.put(intent.getAction(), list);
13673            }
13674            int N = list.size();
13675            int i;
13676            for (i=0; i<N; i++) {
13677                if (intent.filterEquals(list.get(i))) {
13678                    // This sticky already exists, replace it.
13679                    list.set(i, new Intent(intent));
13680                    break;
13681                }
13682            }
13683            if (i >= N) {
13684                list.add(new Intent(intent));
13685            }
13686        }
13687
13688        int[] users;
13689        if (userId == UserHandle.USER_ALL) {
13690            // Caller wants broadcast to go to all started users.
13691            users = mStartedUserArray;
13692        } else {
13693            // Caller wants broadcast to go to one specific user.
13694            users = new int[] {userId};
13695        }
13696
13697        // Figure out who all will receive this broadcast.
13698        List receivers = null;
13699        List<BroadcastFilter> registeredReceivers = null;
13700        // Need to resolve the intent to interested receivers...
13701        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13702                 == 0) {
13703            receivers = collectReceiverComponents(intent, resolvedType, users);
13704        }
13705        if (intent.getComponent() == null) {
13706            registeredReceivers = mReceiverResolver.queryIntent(intent,
13707                    resolvedType, false, userId);
13708        }
13709
13710        final boolean replacePending =
13711                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13712
13713        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13714                + " replacePending=" + replacePending);
13715
13716        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13717        if (!ordered && NR > 0) {
13718            // If we are not serializing this broadcast, then send the
13719            // registered receivers separately so they don't wait for the
13720            // components to be launched.
13721            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13722            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13723                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13724                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13725                    ordered, sticky, false, userId);
13726            if (DEBUG_BROADCAST) Slog.v(
13727                    TAG, "Enqueueing parallel broadcast " + r);
13728            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13729            if (!replaced) {
13730                queue.enqueueParallelBroadcastLocked(r);
13731                queue.scheduleBroadcastsLocked();
13732            }
13733            registeredReceivers = null;
13734            NR = 0;
13735        }
13736
13737        // Merge into one list.
13738        int ir = 0;
13739        if (receivers != null) {
13740            // A special case for PACKAGE_ADDED: do not allow the package
13741            // being added to see this broadcast.  This prevents them from
13742            // using this as a back door to get run as soon as they are
13743            // installed.  Maybe in the future we want to have a special install
13744            // broadcast or such for apps, but we'd like to deliberately make
13745            // this decision.
13746            String skipPackages[] = null;
13747            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13748                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13749                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13750                Uri data = intent.getData();
13751                if (data != null) {
13752                    String pkgName = data.getSchemeSpecificPart();
13753                    if (pkgName != null) {
13754                        skipPackages = new String[] { pkgName };
13755                    }
13756                }
13757            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13758                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13759            }
13760            if (skipPackages != null && (skipPackages.length > 0)) {
13761                for (String skipPackage : skipPackages) {
13762                    if (skipPackage != null) {
13763                        int NT = receivers.size();
13764                        for (int it=0; it<NT; it++) {
13765                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13766                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13767                                receivers.remove(it);
13768                                it--;
13769                                NT--;
13770                            }
13771                        }
13772                    }
13773                }
13774            }
13775
13776            int NT = receivers != null ? receivers.size() : 0;
13777            int it = 0;
13778            ResolveInfo curt = null;
13779            BroadcastFilter curr = null;
13780            while (it < NT && ir < NR) {
13781                if (curt == null) {
13782                    curt = (ResolveInfo)receivers.get(it);
13783                }
13784                if (curr == null) {
13785                    curr = registeredReceivers.get(ir);
13786                }
13787                if (curr.getPriority() >= curt.priority) {
13788                    // Insert this broadcast record into the final list.
13789                    receivers.add(it, curr);
13790                    ir++;
13791                    curr = null;
13792                    it++;
13793                    NT++;
13794                } else {
13795                    // Skip to the next ResolveInfo in the final list.
13796                    it++;
13797                    curt = null;
13798                }
13799            }
13800        }
13801        while (ir < NR) {
13802            if (receivers == null) {
13803                receivers = new ArrayList();
13804            }
13805            receivers.add(registeredReceivers.get(ir));
13806            ir++;
13807        }
13808
13809        if ((receivers != null && receivers.size() > 0)
13810                || resultTo != null) {
13811            BroadcastQueue queue = broadcastQueueForIntent(intent);
13812            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13813                    callerPackage, callingPid, callingUid, resolvedType,
13814                    requiredPermission, appOp, receivers, resultTo, resultCode,
13815                    resultData, map, ordered, sticky, false, userId);
13816            if (DEBUG_BROADCAST) Slog.v(
13817                    TAG, "Enqueueing ordered broadcast " + r
13818                    + ": prev had " + queue.mOrderedBroadcasts.size());
13819            if (DEBUG_BROADCAST) {
13820                int seq = r.intent.getIntExtra("seq", -1);
13821                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13822            }
13823            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13824            if (!replaced) {
13825                queue.enqueueOrderedBroadcastLocked(r);
13826                queue.scheduleBroadcastsLocked();
13827            }
13828        }
13829
13830        return ActivityManager.BROADCAST_SUCCESS;
13831    }
13832
13833    final Intent verifyBroadcastLocked(Intent intent) {
13834        // Refuse possible leaked file descriptors
13835        if (intent != null && intent.hasFileDescriptors() == true) {
13836            throw new IllegalArgumentException("File descriptors passed in Intent");
13837        }
13838
13839        int flags = intent.getFlags();
13840
13841        if (!mProcessesReady) {
13842            // if the caller really truly claims to know what they're doing, go
13843            // ahead and allow the broadcast without launching any receivers
13844            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13845                intent = new Intent(intent);
13846                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13847            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13848                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13849                        + " before boot completion");
13850                throw new IllegalStateException("Cannot broadcast before boot completed");
13851            }
13852        }
13853
13854        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13855            throw new IllegalArgumentException(
13856                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13857        }
13858
13859        return intent;
13860    }
13861
13862    public final int broadcastIntent(IApplicationThread caller,
13863            Intent intent, String resolvedType, IIntentReceiver resultTo,
13864            int resultCode, String resultData, Bundle map,
13865            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13866        enforceNotIsolatedCaller("broadcastIntent");
13867        synchronized(this) {
13868            intent = verifyBroadcastLocked(intent);
13869
13870            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13871            final int callingPid = Binder.getCallingPid();
13872            final int callingUid = Binder.getCallingUid();
13873            final long origId = Binder.clearCallingIdentity();
13874            int res = broadcastIntentLocked(callerApp,
13875                    callerApp != null ? callerApp.info.packageName : null,
13876                    intent, resolvedType, resultTo,
13877                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13878                    callingPid, callingUid, userId);
13879            Binder.restoreCallingIdentity(origId);
13880            return res;
13881        }
13882    }
13883
13884    int broadcastIntentInPackage(String packageName, int uid,
13885            Intent intent, String resolvedType, IIntentReceiver resultTo,
13886            int resultCode, String resultData, Bundle map,
13887            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13888        synchronized(this) {
13889            intent = verifyBroadcastLocked(intent);
13890
13891            final long origId = Binder.clearCallingIdentity();
13892            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13893                    resultTo, resultCode, resultData, map, requiredPermission,
13894                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13895            Binder.restoreCallingIdentity(origId);
13896            return res;
13897        }
13898    }
13899
13900    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13901        // Refuse possible leaked file descriptors
13902        if (intent != null && intent.hasFileDescriptors() == true) {
13903            throw new IllegalArgumentException("File descriptors passed in Intent");
13904        }
13905
13906        userId = handleIncomingUser(Binder.getCallingPid(),
13907                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13908
13909        synchronized(this) {
13910            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13911                    != PackageManager.PERMISSION_GRANTED) {
13912                String msg = "Permission Denial: unbroadcastIntent() from pid="
13913                        + Binder.getCallingPid()
13914                        + ", uid=" + Binder.getCallingUid()
13915                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13916                Slog.w(TAG, msg);
13917                throw new SecurityException(msg);
13918            }
13919            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13920            if (stickies != null) {
13921                ArrayList<Intent> list = stickies.get(intent.getAction());
13922                if (list != null) {
13923                    int N = list.size();
13924                    int i;
13925                    for (i=0; i<N; i++) {
13926                        if (intent.filterEquals(list.get(i))) {
13927                            list.remove(i);
13928                            break;
13929                        }
13930                    }
13931                    if (list.size() <= 0) {
13932                        stickies.remove(intent.getAction());
13933                    }
13934                }
13935                if (stickies.size() <= 0) {
13936                    mStickyBroadcasts.remove(userId);
13937                }
13938            }
13939        }
13940    }
13941
13942    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13943            String resultData, Bundle resultExtras, boolean resultAbort) {
13944        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13945        if (r == null) {
13946            Slog.w(TAG, "finishReceiver called but not found on queue");
13947            return false;
13948        }
13949
13950        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13951    }
13952
13953    void backgroundServicesFinishedLocked(int userId) {
13954        for (BroadcastQueue queue : mBroadcastQueues) {
13955            queue.backgroundServicesFinishedLocked(userId);
13956        }
13957    }
13958
13959    public void finishReceiver(IBinder who, int resultCode, String resultData,
13960            Bundle resultExtras, boolean resultAbort) {
13961        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13962
13963        // Refuse possible leaked file descriptors
13964        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13965            throw new IllegalArgumentException("File descriptors passed in Bundle");
13966        }
13967
13968        final long origId = Binder.clearCallingIdentity();
13969        try {
13970            boolean doNext = false;
13971            BroadcastRecord r;
13972
13973            synchronized(this) {
13974                r = broadcastRecordForReceiverLocked(who);
13975                if (r != null) {
13976                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13977                        resultData, resultExtras, resultAbort, true);
13978                }
13979            }
13980
13981            if (doNext) {
13982                r.queue.processNextBroadcast(false);
13983            }
13984            trimApplications();
13985        } finally {
13986            Binder.restoreCallingIdentity(origId);
13987        }
13988    }
13989
13990    // =========================================================
13991    // INSTRUMENTATION
13992    // =========================================================
13993
13994    public boolean startInstrumentation(ComponentName className,
13995            String profileFile, int flags, Bundle arguments,
13996            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13997            int userId) {
13998        enforceNotIsolatedCaller("startInstrumentation");
13999        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14000                userId, false, true, "startInstrumentation", null);
14001        // Refuse possible leaked file descriptors
14002        if (arguments != null && arguments.hasFileDescriptors()) {
14003            throw new IllegalArgumentException("File descriptors passed in Bundle");
14004        }
14005
14006        synchronized(this) {
14007            InstrumentationInfo ii = null;
14008            ApplicationInfo ai = null;
14009            try {
14010                ii = mContext.getPackageManager().getInstrumentationInfo(
14011                    className, STOCK_PM_FLAGS);
14012                ai = AppGlobals.getPackageManager().getApplicationInfo(
14013                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14014            } catch (PackageManager.NameNotFoundException e) {
14015            } catch (RemoteException e) {
14016            }
14017            if (ii == null) {
14018                reportStartInstrumentationFailure(watcher, className,
14019                        "Unable to find instrumentation info for: " + className);
14020                return false;
14021            }
14022            if (ai == null) {
14023                reportStartInstrumentationFailure(watcher, className,
14024                        "Unable to find instrumentation target package: " + ii.targetPackage);
14025                return false;
14026            }
14027
14028            int match = mContext.getPackageManager().checkSignatures(
14029                    ii.targetPackage, ii.packageName);
14030            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14031                String msg = "Permission Denial: starting instrumentation "
14032                        + className + " from pid="
14033                        + Binder.getCallingPid()
14034                        + ", uid=" + Binder.getCallingPid()
14035                        + " not allowed because package " + ii.packageName
14036                        + " does not have a signature matching the target "
14037                        + ii.targetPackage;
14038                reportStartInstrumentationFailure(watcher, className, msg);
14039                throw new SecurityException(msg);
14040            }
14041
14042            final long origId = Binder.clearCallingIdentity();
14043            // Instrumentation can kill and relaunch even persistent processes
14044            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14045                    "start instr");
14046            ProcessRecord app = addAppLocked(ai, false);
14047            app.instrumentationClass = className;
14048            app.instrumentationInfo = ai;
14049            app.instrumentationProfileFile = profileFile;
14050            app.instrumentationArguments = arguments;
14051            app.instrumentationWatcher = watcher;
14052            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14053            app.instrumentationResultClass = className;
14054            Binder.restoreCallingIdentity(origId);
14055        }
14056
14057        return true;
14058    }
14059
14060    /**
14061     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14062     * error to the logs, but if somebody is watching, send the report there too.  This enables
14063     * the "am" command to report errors with more information.
14064     *
14065     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14066     * @param cn The component name of the instrumentation.
14067     * @param report The error report.
14068     */
14069    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14070            ComponentName cn, String report) {
14071        Slog.w(TAG, report);
14072        try {
14073            if (watcher != null) {
14074                Bundle results = new Bundle();
14075                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14076                results.putString("Error", report);
14077                watcher.instrumentationStatus(cn, -1, results);
14078            }
14079        } catch (RemoteException e) {
14080            Slog.w(TAG, e);
14081        }
14082    }
14083
14084    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14085        if (app.instrumentationWatcher != null) {
14086            try {
14087                // NOTE:  IInstrumentationWatcher *must* be oneway here
14088                app.instrumentationWatcher.instrumentationFinished(
14089                    app.instrumentationClass,
14090                    resultCode,
14091                    results);
14092            } catch (RemoteException e) {
14093            }
14094        }
14095        if (app.instrumentationUiAutomationConnection != null) {
14096            try {
14097                app.instrumentationUiAutomationConnection.shutdown();
14098            } catch (RemoteException re) {
14099                /* ignore */
14100            }
14101            // Only a UiAutomation can set this flag and now that
14102            // it is finished we make sure it is reset to its default.
14103            mUserIsMonkey = false;
14104        }
14105        app.instrumentationWatcher = null;
14106        app.instrumentationUiAutomationConnection = null;
14107        app.instrumentationClass = null;
14108        app.instrumentationInfo = null;
14109        app.instrumentationProfileFile = null;
14110        app.instrumentationArguments = null;
14111
14112        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14113                "finished inst");
14114    }
14115
14116    public void finishInstrumentation(IApplicationThread target,
14117            int resultCode, Bundle results) {
14118        int userId = UserHandle.getCallingUserId();
14119        // Refuse possible leaked file descriptors
14120        if (results != null && results.hasFileDescriptors()) {
14121            throw new IllegalArgumentException("File descriptors passed in Intent");
14122        }
14123
14124        synchronized(this) {
14125            ProcessRecord app = getRecordForAppLocked(target);
14126            if (app == null) {
14127                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14128                return;
14129            }
14130            final long origId = Binder.clearCallingIdentity();
14131            finishInstrumentationLocked(app, resultCode, results);
14132            Binder.restoreCallingIdentity(origId);
14133        }
14134    }
14135
14136    // =========================================================
14137    // CONFIGURATION
14138    // =========================================================
14139
14140    public ConfigurationInfo getDeviceConfigurationInfo() {
14141        ConfigurationInfo config = new ConfigurationInfo();
14142        synchronized (this) {
14143            config.reqTouchScreen = mConfiguration.touchscreen;
14144            config.reqKeyboardType = mConfiguration.keyboard;
14145            config.reqNavigation = mConfiguration.navigation;
14146            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14147                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14148                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14149            }
14150            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14151                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14152                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14153            }
14154            config.reqGlEsVersion = GL_ES_VERSION;
14155        }
14156        return config;
14157    }
14158
14159    ActivityStack getFocusedStack() {
14160        return mStackSupervisor.getFocusedStack();
14161    }
14162
14163    public Configuration getConfiguration() {
14164        Configuration ci;
14165        synchronized(this) {
14166            ci = new Configuration(mConfiguration);
14167        }
14168        return ci;
14169    }
14170
14171    public void updatePersistentConfiguration(Configuration values) {
14172        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14173                "updateConfiguration()");
14174        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14175                "updateConfiguration()");
14176        if (values == null) {
14177            throw new NullPointerException("Configuration must not be null");
14178        }
14179
14180        synchronized(this) {
14181            final long origId = Binder.clearCallingIdentity();
14182            updateConfigurationLocked(values, null, true, false);
14183            Binder.restoreCallingIdentity(origId);
14184        }
14185    }
14186
14187    public void updateConfiguration(Configuration values) {
14188        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14189                "updateConfiguration()");
14190
14191        synchronized(this) {
14192            if (values == null && mWindowManager != null) {
14193                // sentinel: fetch the current configuration from the window manager
14194                values = mWindowManager.computeNewConfiguration();
14195            }
14196
14197            if (mWindowManager != null) {
14198                mProcessList.applyDisplaySize(mWindowManager);
14199            }
14200
14201            final long origId = Binder.clearCallingIdentity();
14202            if (values != null) {
14203                Settings.System.clearConfiguration(values);
14204            }
14205            updateConfigurationLocked(values, null, false, false);
14206            Binder.restoreCallingIdentity(origId);
14207        }
14208    }
14209
14210    /**
14211     * Do either or both things: (1) change the current configuration, and (2)
14212     * make sure the given activity is running with the (now) current
14213     * configuration.  Returns true if the activity has been left running, or
14214     * false if <var>starting</var> is being destroyed to match the new
14215     * configuration.
14216     * @param persistent TODO
14217     */
14218    boolean updateConfigurationLocked(Configuration values,
14219            ActivityRecord starting, boolean persistent, boolean initLocale) {
14220        int changes = 0;
14221
14222        if (values != null) {
14223            Configuration newConfig = new Configuration(mConfiguration);
14224            changes = newConfig.updateFrom(values);
14225            if (changes != 0) {
14226                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14227                    Slog.i(TAG, "Updating configuration to: " + values);
14228                }
14229
14230                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14231
14232                if (values.locale != null && !initLocale) {
14233                    saveLocaleLocked(values.locale,
14234                                     !values.locale.equals(mConfiguration.locale),
14235                                     values.userSetLocale);
14236                }
14237
14238                mConfigurationSeq++;
14239                if (mConfigurationSeq <= 0) {
14240                    mConfigurationSeq = 1;
14241                }
14242                newConfig.seq = mConfigurationSeq;
14243                mConfiguration = newConfig;
14244                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14245
14246                final Configuration configCopy = new Configuration(mConfiguration);
14247
14248                // TODO: If our config changes, should we auto dismiss any currently
14249                // showing dialogs?
14250                mShowDialogs = shouldShowDialogs(newConfig);
14251
14252                AttributeCache ac = AttributeCache.instance();
14253                if (ac != null) {
14254                    ac.updateConfiguration(configCopy);
14255                }
14256
14257                // Make sure all resources in our process are updated
14258                // right now, so that anyone who is going to retrieve
14259                // resource values after we return will be sure to get
14260                // the new ones.  This is especially important during
14261                // boot, where the first config change needs to guarantee
14262                // all resources have that config before following boot
14263                // code is executed.
14264                mSystemThread.applyConfigurationToResources(configCopy);
14265
14266                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14267                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14268                    msg.obj = new Configuration(configCopy);
14269                    mHandler.sendMessage(msg);
14270                }
14271
14272                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14273                    ProcessRecord app = mLruProcesses.get(i);
14274                    try {
14275                        if (app.thread != null) {
14276                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14277                                    + app.processName + " new config " + mConfiguration);
14278                            app.thread.scheduleConfigurationChanged(configCopy);
14279                        }
14280                    } catch (Exception e) {
14281                    }
14282                }
14283                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14284                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14285                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14286                        | Intent.FLAG_RECEIVER_FOREGROUND);
14287                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14288                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14289                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14290                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14291                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14292                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14293                    broadcastIntentLocked(null, null, intent,
14294                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14295                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14296                }
14297            }
14298        }
14299
14300        boolean kept = true;
14301        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14302        // mainStack is null during startup.
14303        if (mainStack != null) {
14304            if (changes != 0 && starting == null) {
14305                // If the configuration changed, and the caller is not already
14306                // in the process of starting an activity, then find the top
14307                // activity to check if its configuration needs to change.
14308                starting = mainStack.topRunningActivityLocked(null);
14309            }
14310
14311            if (starting != null) {
14312                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14313                // And we need to make sure at this point that all other activities
14314                // are made visible with the correct configuration.
14315                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14316            }
14317        }
14318
14319        if (values != null && mWindowManager != null) {
14320            mWindowManager.setNewConfiguration(mConfiguration);
14321        }
14322
14323        return kept;
14324    }
14325
14326    /**
14327     * Decide based on the configuration whether we should shouw the ANR,
14328     * crash, etc dialogs.  The idea is that if there is no affordnace to
14329     * press the on-screen buttons, we shouldn't show the dialog.
14330     *
14331     * A thought: SystemUI might also want to get told about this, the Power
14332     * dialog / global actions also might want different behaviors.
14333     */
14334    private static final boolean shouldShowDialogs(Configuration config) {
14335        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14336                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14337    }
14338
14339    /**
14340     * Save the locale.  You must be inside a synchronized (this) block.
14341     */
14342    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14343        if(isDiff) {
14344            SystemProperties.set("user.language", l.getLanguage());
14345            SystemProperties.set("user.region", l.getCountry());
14346        }
14347
14348        if(isPersist) {
14349            SystemProperties.set("persist.sys.language", l.getLanguage());
14350            SystemProperties.set("persist.sys.country", l.getCountry());
14351            SystemProperties.set("persist.sys.localevar", l.getVariant());
14352        }
14353    }
14354
14355    @Override
14356    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14357        ActivityRecord srec = ActivityRecord.forToken(token);
14358        return srec != null && srec.task.affinity != null &&
14359                srec.task.affinity.equals(destAffinity);
14360    }
14361
14362    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14363            Intent resultData) {
14364
14365        synchronized (this) {
14366            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14367            if (stack != null) {
14368                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14369            }
14370            return false;
14371        }
14372    }
14373
14374    public int getLaunchedFromUid(IBinder activityToken) {
14375        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14376        if (srec == null) {
14377            return -1;
14378        }
14379        return srec.launchedFromUid;
14380    }
14381
14382    public String getLaunchedFromPackage(IBinder activityToken) {
14383        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14384        if (srec == null) {
14385            return null;
14386        }
14387        return srec.launchedFromPackage;
14388    }
14389
14390    // =========================================================
14391    // LIFETIME MANAGEMENT
14392    // =========================================================
14393
14394    // Returns which broadcast queue the app is the current [or imminent] receiver
14395    // on, or 'null' if the app is not an active broadcast recipient.
14396    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14397        BroadcastRecord r = app.curReceiver;
14398        if (r != null) {
14399            return r.queue;
14400        }
14401
14402        // It's not the current receiver, but it might be starting up to become one
14403        synchronized (this) {
14404            for (BroadcastQueue queue : mBroadcastQueues) {
14405                r = queue.mPendingBroadcast;
14406                if (r != null && r.curApp == app) {
14407                    // found it; report which queue it's in
14408                    return queue;
14409                }
14410            }
14411        }
14412
14413        return null;
14414    }
14415
14416    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14417            boolean doingAll, long now) {
14418        if (mAdjSeq == app.adjSeq) {
14419            // This adjustment has already been computed.
14420            return app.curRawAdj;
14421        }
14422
14423        if (app.thread == null) {
14424            app.adjSeq = mAdjSeq;
14425            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14426            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14427            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14428        }
14429
14430        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14431        app.adjSource = null;
14432        app.adjTarget = null;
14433        app.empty = false;
14434        app.cached = false;
14435
14436        final int activitiesSize = app.activities.size();
14437
14438        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14439            // The max adjustment doesn't allow this app to be anything
14440            // below foreground, so it is not worth doing work for it.
14441            app.adjType = "fixed";
14442            app.adjSeq = mAdjSeq;
14443            app.curRawAdj = app.maxAdj;
14444            app.foregroundActivities = false;
14445            app.keeping = true;
14446            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14447            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14448            // System process can do UI, and when they do we want to have
14449            // them trim their memory after the user leaves the UI.  To
14450            // facilitate this, here we need to determine whether or not it
14451            // is currently showing UI.
14452            app.systemNoUi = true;
14453            if (app == TOP_APP) {
14454                app.systemNoUi = false;
14455            } else if (activitiesSize > 0) {
14456                for (int j = 0; j < activitiesSize; j++) {
14457                    final ActivityRecord r = app.activities.get(j);
14458                    if (r.visible) {
14459                        app.systemNoUi = false;
14460                    }
14461                }
14462            }
14463            if (!app.systemNoUi) {
14464                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14465            }
14466            return (app.curAdj=app.maxAdj);
14467        }
14468
14469        app.keeping = false;
14470        app.systemNoUi = false;
14471
14472        // Determine the importance of the process, starting with most
14473        // important to least, and assign an appropriate OOM adjustment.
14474        int adj;
14475        int schedGroup;
14476        int procState;
14477        boolean foregroundActivities = false;
14478        boolean interesting = false;
14479        BroadcastQueue queue;
14480        if (app == TOP_APP) {
14481            // The last app on the list is the foreground app.
14482            adj = ProcessList.FOREGROUND_APP_ADJ;
14483            schedGroup = Process.THREAD_GROUP_DEFAULT;
14484            app.adjType = "top-activity";
14485            foregroundActivities = true;
14486            interesting = true;
14487            procState = ActivityManager.PROCESS_STATE_TOP;
14488        } else if (app.instrumentationClass != null) {
14489            // Don't want to kill running instrumentation.
14490            adj = ProcessList.FOREGROUND_APP_ADJ;
14491            schedGroup = Process.THREAD_GROUP_DEFAULT;
14492            app.adjType = "instrumentation";
14493            interesting = true;
14494            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14495        } else if ((queue = isReceivingBroadcast(app)) != null) {
14496            // An app that is currently receiving a broadcast also
14497            // counts as being in the foreground for OOM killer purposes.
14498            // It's placed in a sched group based on the nature of the
14499            // broadcast as reflected by which queue it's active in.
14500            adj = ProcessList.FOREGROUND_APP_ADJ;
14501            schedGroup = (queue == mFgBroadcastQueue)
14502                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14503            app.adjType = "broadcast";
14504            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14505        } else if (app.executingServices.size() > 0) {
14506            // An app that is currently executing a service callback also
14507            // counts as being in the foreground.
14508            adj = ProcessList.FOREGROUND_APP_ADJ;
14509            schedGroup = app.execServicesFg ?
14510                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14511            app.adjType = "exec-service";
14512            procState = ActivityManager.PROCESS_STATE_SERVICE;
14513            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14514        } else {
14515            // As far as we know the process is empty.  We may change our mind later.
14516            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14517            // At this point we don't actually know the adjustment.  Use the cached adj
14518            // value that the caller wants us to.
14519            adj = cachedAdj;
14520            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14521            app.cached = true;
14522            app.empty = true;
14523            app.adjType = "cch-empty";
14524        }
14525
14526        // Examine all activities if not already foreground.
14527        if (!foregroundActivities && activitiesSize > 0) {
14528            for (int j = 0; j < activitiesSize; j++) {
14529                final ActivityRecord r = app.activities.get(j);
14530                if (r.app != app) {
14531                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14532                            + app + "?!?");
14533                    continue;
14534                }
14535                if (r.visible) {
14536                    // App has a visible activity; only upgrade adjustment.
14537                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14538                        adj = ProcessList.VISIBLE_APP_ADJ;
14539                        app.adjType = "visible";
14540                    }
14541                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14542                        procState = ActivityManager.PROCESS_STATE_TOP;
14543                    }
14544                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14545                    app.cached = false;
14546                    app.empty = false;
14547                    foregroundActivities = true;
14548                    break;
14549                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14550                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14551                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14552                        app.adjType = "pausing";
14553                    }
14554                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14555                        procState = ActivityManager.PROCESS_STATE_TOP;
14556                    }
14557                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14558                    app.cached = false;
14559                    app.empty = false;
14560                    foregroundActivities = true;
14561                } else if (r.state == ActivityState.STOPPING) {
14562                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14563                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14564                        app.adjType = "stopping";
14565                    }
14566                    // For the process state, we will at this point consider the
14567                    // process to be cached.  It will be cached either as an activity
14568                    // or empty depending on whether the activity is finishing.  We do
14569                    // this so that we can treat the process as cached for purposes of
14570                    // memory trimming (determing current memory level, trim command to
14571                    // send to process) since there can be an arbitrary number of stopping
14572                    // processes and they should soon all go into the cached state.
14573                    if (!r.finishing) {
14574                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14575                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14576                        }
14577                    }
14578                    app.cached = false;
14579                    app.empty = false;
14580                    foregroundActivities = true;
14581                } else {
14582                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14583                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14584                        app.adjType = "cch-act";
14585                    }
14586                }
14587            }
14588        }
14589
14590        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14591            if (app.foregroundServices) {
14592                // The user is aware of this app, so make it visible.
14593                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14594                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14595                app.cached = false;
14596                app.adjType = "fg-service";
14597                schedGroup = Process.THREAD_GROUP_DEFAULT;
14598            } else if (app.forcingToForeground != null) {
14599                // The user is aware of this app, so make it visible.
14600                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14601                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14602                app.cached = false;
14603                app.adjType = "force-fg";
14604                app.adjSource = app.forcingToForeground;
14605                schedGroup = Process.THREAD_GROUP_DEFAULT;
14606            }
14607        }
14608
14609        if (app.foregroundServices) {
14610            interesting = true;
14611        }
14612
14613        if (app == mHeavyWeightProcess) {
14614            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14615                // We don't want to kill the current heavy-weight process.
14616                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14617                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14618                app.cached = false;
14619                app.adjType = "heavy";
14620            }
14621            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14622                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14623            }
14624        }
14625
14626        if (app == mHomeProcess) {
14627            if (adj > ProcessList.HOME_APP_ADJ) {
14628                // This process is hosting what we currently consider to be the
14629                // home app, so we don't want to let it go into the background.
14630                adj = ProcessList.HOME_APP_ADJ;
14631                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14632                app.cached = false;
14633                app.adjType = "home";
14634            }
14635            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14636                procState = ActivityManager.PROCESS_STATE_HOME;
14637            }
14638        }
14639
14640        if (app == mPreviousProcess && app.activities.size() > 0) {
14641            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14642                // This was the previous process that showed UI to the user.
14643                // We want to try to keep it around more aggressively, to give
14644                // a good experience around switching between two apps.
14645                adj = ProcessList.PREVIOUS_APP_ADJ;
14646                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14647                app.cached = false;
14648                app.adjType = "previous";
14649            }
14650            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14651                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14652            }
14653        }
14654
14655        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14656                + " reason=" + app.adjType);
14657
14658        // By default, we use the computed adjustment.  It may be changed if
14659        // there are applications dependent on our services or providers, but
14660        // this gives us a baseline and makes sure we don't get into an
14661        // infinite recursion.
14662        app.adjSeq = mAdjSeq;
14663        app.curRawAdj = adj;
14664        app.hasStartedServices = false;
14665
14666        if (mBackupTarget != null && app == mBackupTarget.app) {
14667            // If possible we want to avoid killing apps while they're being backed up
14668            if (adj > ProcessList.BACKUP_APP_ADJ) {
14669                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14670                adj = ProcessList.BACKUP_APP_ADJ;
14671                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14672                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14673                }
14674                app.adjType = "backup";
14675                app.cached = false;
14676            }
14677            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14678                procState = ActivityManager.PROCESS_STATE_BACKUP;
14679            }
14680        }
14681
14682        boolean mayBeTop = false;
14683
14684        for (int is = app.services.size()-1;
14685                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14686                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14687                        || procState > ActivityManager.PROCESS_STATE_TOP);
14688                is--) {
14689            ServiceRecord s = app.services.valueAt(is);
14690            if (s.startRequested) {
14691                app.hasStartedServices = true;
14692                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14693                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14694                }
14695                if (app.hasShownUi && app != mHomeProcess) {
14696                    // If this process has shown some UI, let it immediately
14697                    // go to the LRU list because it may be pretty heavy with
14698                    // UI stuff.  We'll tag it with a label just to help
14699                    // debug and understand what is going on.
14700                    if (adj > ProcessList.SERVICE_ADJ) {
14701                        app.adjType = "cch-started-ui-services";
14702                    }
14703                } else {
14704                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14705                        // This service has seen some activity within
14706                        // recent memory, so we will keep its process ahead
14707                        // of the background processes.
14708                        if (adj > ProcessList.SERVICE_ADJ) {
14709                            adj = ProcessList.SERVICE_ADJ;
14710                            app.adjType = "started-services";
14711                            app.cached = false;
14712                        }
14713                    }
14714                    // If we have let the service slide into the background
14715                    // state, still have some text describing what it is doing
14716                    // even though the service no longer has an impact.
14717                    if (adj > ProcessList.SERVICE_ADJ) {
14718                        app.adjType = "cch-started-services";
14719                    }
14720                }
14721                // Don't kill this process because it is doing work; it
14722                // has said it is doing work.
14723                app.keeping = true;
14724            }
14725            for (int conni = s.connections.size()-1;
14726                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14727                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14728                            || procState > ActivityManager.PROCESS_STATE_TOP);
14729                    conni--) {
14730                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14731                for (int i = 0;
14732                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14733                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14734                                || procState > ActivityManager.PROCESS_STATE_TOP);
14735                        i++) {
14736                    // XXX should compute this based on the max of
14737                    // all connected clients.
14738                    ConnectionRecord cr = clist.get(i);
14739                    if (cr.binding.client == app) {
14740                        // Binding to ourself is not interesting.
14741                        continue;
14742                    }
14743                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14744                        ProcessRecord client = cr.binding.client;
14745                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14746                                TOP_APP, doingAll, now);
14747                        int clientProcState = client.curProcState;
14748                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14749                            // If the other app is cached for any reason, for purposes here
14750                            // we are going to consider it empty.  The specific cached state
14751                            // doesn't propagate except under certain conditions.
14752                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14753                        }
14754                        String adjType = null;
14755                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14756                            // Not doing bind OOM management, so treat
14757                            // this guy more like a started service.
14758                            if (app.hasShownUi && app != mHomeProcess) {
14759                                // If this process has shown some UI, let it immediately
14760                                // go to the LRU list because it may be pretty heavy with
14761                                // UI stuff.  We'll tag it with a label just to help
14762                                // debug and understand what is going on.
14763                                if (adj > clientAdj) {
14764                                    adjType = "cch-bound-ui-services";
14765                                }
14766                                app.cached = false;
14767                                clientAdj = adj;
14768                                clientProcState = procState;
14769                            } else {
14770                                if (now >= (s.lastActivity
14771                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14772                                    // This service has not seen activity within
14773                                    // recent memory, so allow it to drop to the
14774                                    // LRU list if there is no other reason to keep
14775                                    // it around.  We'll also tag it with a label just
14776                                    // to help debug and undertand what is going on.
14777                                    if (adj > clientAdj) {
14778                                        adjType = "cch-bound-services";
14779                                    }
14780                                    clientAdj = adj;
14781                                }
14782                            }
14783                        }
14784                        if (adj > clientAdj) {
14785                            // If this process has recently shown UI, and
14786                            // the process that is binding to it is less
14787                            // important than being visible, then we don't
14788                            // care about the binding as much as we care
14789                            // about letting this process get into the LRU
14790                            // list to be killed and restarted if needed for
14791                            // memory.
14792                            if (app.hasShownUi && app != mHomeProcess
14793                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14794                                adjType = "cch-bound-ui-services";
14795                            } else {
14796                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14797                                        |Context.BIND_IMPORTANT)) != 0) {
14798                                    adj = clientAdj;
14799                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14800                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14801                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14802                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14803                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14804                                    adj = clientAdj;
14805                                } else {
14806                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14807                                        adj = ProcessList.VISIBLE_APP_ADJ;
14808                                    }
14809                                }
14810                                if (!client.cached) {
14811                                    app.cached = false;
14812                                }
14813                                if (client.keeping) {
14814                                    app.keeping = true;
14815                                }
14816                                adjType = "service";
14817                            }
14818                        }
14819                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14820                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14821                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14822                            }
14823                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14824                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14825                                    // Special handling of clients who are in the top state.
14826                                    // We *may* want to consider this process to be in the
14827                                    // top state as well, but only if there is not another
14828                                    // reason for it to be running.  Being on the top is a
14829                                    // special state, meaning you are specifically running
14830                                    // for the current top app.  If the process is already
14831                                    // running in the background for some other reason, it
14832                                    // is more important to continue considering it to be
14833                                    // in the background state.
14834                                    mayBeTop = true;
14835                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14836                                } else {
14837                                    // Special handling for above-top states (persistent
14838                                    // processes).  These should not bring the current process
14839                                    // into the top state, since they are not on top.  Instead
14840                                    // give them the best state after that.
14841                                    clientProcState =
14842                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14843                                }
14844                            }
14845                        } else {
14846                            if (clientProcState <
14847                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14848                                clientProcState =
14849                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14850                            }
14851                        }
14852                        if (procState > clientProcState) {
14853                            procState = clientProcState;
14854                        }
14855                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14856                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14857                            app.pendingUiClean = true;
14858                        }
14859                        if (adjType != null) {
14860                            app.adjType = adjType;
14861                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14862                                    .REASON_SERVICE_IN_USE;
14863                            app.adjSource = cr.binding.client;
14864                            app.adjSourceOom = clientAdj;
14865                            app.adjTarget = s.name;
14866                        }
14867                    }
14868                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
14869                        app.treatLikeActivity = true;
14870                    }
14871                    final ActivityRecord a = cr.activity;
14872                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14873                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14874                                (a.visible || a.state == ActivityState.RESUMED
14875                                 || a.state == ActivityState.PAUSING)) {
14876                            adj = ProcessList.FOREGROUND_APP_ADJ;
14877                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14878                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14879                            }
14880                            app.cached = false;
14881                            app.adjType = "service";
14882                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14883                                    .REASON_SERVICE_IN_USE;
14884                            app.adjSource = a;
14885                            app.adjSourceOom = adj;
14886                            app.adjTarget = s.name;
14887                        }
14888                    }
14889                }
14890            }
14891        }
14892
14893        for (int provi = app.pubProviders.size()-1;
14894                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14895                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14896                        || procState > ActivityManager.PROCESS_STATE_TOP);
14897                provi--) {
14898            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14899            for (int i = cpr.connections.size()-1;
14900                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14901                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14902                            || procState > ActivityManager.PROCESS_STATE_TOP);
14903                    i--) {
14904                ContentProviderConnection conn = cpr.connections.get(i);
14905                ProcessRecord client = conn.client;
14906                if (client == app) {
14907                    // Being our own client is not interesting.
14908                    continue;
14909                }
14910                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14911                int clientProcState = client.curProcState;
14912                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14913                    // If the other app is cached for any reason, for purposes here
14914                    // we are going to consider it empty.
14915                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14916                }
14917                if (adj > clientAdj) {
14918                    if (app.hasShownUi && app != mHomeProcess
14919                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14920                        app.adjType = "cch-ui-provider";
14921                    } else {
14922                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14923                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14924                        app.adjType = "provider";
14925                    }
14926                    app.cached &= client.cached;
14927                    app.keeping |= client.keeping;
14928                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14929                            .REASON_PROVIDER_IN_USE;
14930                    app.adjSource = client;
14931                    app.adjSourceOom = clientAdj;
14932                    app.adjTarget = cpr.name;
14933                }
14934                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14935                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14936                        // Special handling of clients who are in the top state.
14937                        // We *may* want to consider this process to be in the
14938                        // top state as well, but only if there is not another
14939                        // reason for it to be running.  Being on the top is a
14940                        // special state, meaning you are specifically running
14941                        // for the current top app.  If the process is already
14942                        // running in the background for some other reason, it
14943                        // is more important to continue considering it to be
14944                        // in the background state.
14945                        mayBeTop = true;
14946                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14947                    } else {
14948                        // Special handling for above-top states (persistent
14949                        // processes).  These should not bring the current process
14950                        // into the top state, since they are not on top.  Instead
14951                        // give them the best state after that.
14952                        clientProcState =
14953                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14954                    }
14955                }
14956                if (procState > clientProcState) {
14957                    procState = clientProcState;
14958                }
14959                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14960                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14961                }
14962            }
14963            // If the provider has external (non-framework) process
14964            // dependencies, ensure that its adjustment is at least
14965            // FOREGROUND_APP_ADJ.
14966            if (cpr.hasExternalProcessHandles()) {
14967                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14968                    adj = ProcessList.FOREGROUND_APP_ADJ;
14969                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14970                    app.cached = false;
14971                    app.keeping = true;
14972                    app.adjType = "provider";
14973                    app.adjTarget = cpr.name;
14974                }
14975                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14976                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14977                }
14978            }
14979        }
14980
14981        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14982            // A client of one of our services or providers is in the top state.  We
14983            // *may* want to be in the top state, but not if we are already running in
14984            // the background for some other reason.  For the decision here, we are going
14985            // to pick out a few specific states that we want to remain in when a client
14986            // is top (states that tend to be longer-term) and otherwise allow it to go
14987            // to the top state.
14988            switch (procState) {
14989                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14990                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14991                case ActivityManager.PROCESS_STATE_SERVICE:
14992                    // These all are longer-term states, so pull them up to the top
14993                    // of the background states, but not all the way to the top state.
14994                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14995                    break;
14996                default:
14997                    // Otherwise, top is a better choice, so take it.
14998                    procState = ActivityManager.PROCESS_STATE_TOP;
14999                    break;
15000            }
15001        }
15002
15003        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15004            if (app.hasClientActivities) {
15005                // This is a cached process, but with client activities.  Mark it so.
15006                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15007                app.adjType = "cch-client-act";
15008            } else if (app.treatLikeActivity) {
15009                // This is a cached process, but somebody wants us to treat it like it has
15010                // an activity, okay!
15011                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15012                app.adjType = "cch-as-act";
15013            }
15014        }
15015
15016        if (adj == ProcessList.SERVICE_ADJ) {
15017            if (doingAll) {
15018                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15019                mNewNumServiceProcs++;
15020                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15021                if (!app.serviceb) {
15022                    // This service isn't far enough down on the LRU list to
15023                    // normally be a B service, but if we are low on RAM and it
15024                    // is large we want to force it down since we would prefer to
15025                    // keep launcher over it.
15026                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15027                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15028                        app.serviceHighRam = true;
15029                        app.serviceb = true;
15030                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15031                    } else {
15032                        mNewNumAServiceProcs++;
15033                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15034                    }
15035                } else {
15036                    app.serviceHighRam = false;
15037                }
15038            }
15039            if (app.serviceb) {
15040                adj = ProcessList.SERVICE_B_ADJ;
15041            }
15042        }
15043
15044        app.curRawAdj = adj;
15045
15046        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15047        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15048        if (adj > app.maxAdj) {
15049            adj = app.maxAdj;
15050            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15051                schedGroup = Process.THREAD_GROUP_DEFAULT;
15052            }
15053        }
15054        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15055            app.keeping = true;
15056        }
15057
15058        // Do final modification to adj.  Everything we do between here and applying
15059        // the final setAdj must be done in this function, because we will also use
15060        // it when computing the final cached adj later.  Note that we don't need to
15061        // worry about this for max adj above, since max adj will always be used to
15062        // keep it out of the cached vaues.
15063        adj = app.modifyRawOomAdj(adj);
15064
15065        app.curProcState = procState;
15066
15067        int importance = app.memImportance;
15068        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
15069            app.curAdj = adj;
15070            app.curSchedGroup = schedGroup;
15071            if (!interesting) {
15072                // For this reporting, if there is not something explicitly
15073                // interesting in this process then we will push it to the
15074                // background importance.
15075                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15076            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
15077                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15078            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
15079                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15080            } else if (adj >= ProcessList.HOME_APP_ADJ) {
15081                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
15082            } else if (adj >= ProcessList.SERVICE_ADJ) {
15083                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
15084            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15085                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
15086            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
15087                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
15088            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
15089                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
15090            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
15091                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
15092            } else {
15093                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
15094            }
15095        }
15096
15097        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
15098        if (foregroundActivities != app.foregroundActivities) {
15099            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15100        }
15101        if (changes != 0) {
15102            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15103            app.memImportance = importance;
15104            app.foregroundActivities = foregroundActivities;
15105            int i = mPendingProcessChanges.size()-1;
15106            ProcessChangeItem item = null;
15107            while (i >= 0) {
15108                item = mPendingProcessChanges.get(i);
15109                if (item.pid == app.pid) {
15110                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15111                    break;
15112                }
15113                i--;
15114            }
15115            if (i < 0) {
15116                // No existing item in pending changes; need a new one.
15117                final int NA = mAvailProcessChanges.size();
15118                if (NA > 0) {
15119                    item = mAvailProcessChanges.remove(NA-1);
15120                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15121                } else {
15122                    item = new ProcessChangeItem();
15123                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15124                }
15125                item.changes = 0;
15126                item.pid = app.pid;
15127                item.uid = app.info.uid;
15128                if (mPendingProcessChanges.size() == 0) {
15129                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15130                            "*** Enqueueing dispatch processes changed!");
15131                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15132                }
15133                mPendingProcessChanges.add(item);
15134            }
15135            item.changes |= changes;
15136            item.importance = importance;
15137            item.foregroundActivities = foregroundActivities;
15138            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15139                    + Integer.toHexString(System.identityHashCode(item))
15140                    + " " + app.toShortString() + ": changes=" + item.changes
15141                    + " importance=" + item.importance
15142                    + " foreground=" + item.foregroundActivities
15143                    + " type=" + app.adjType + " source=" + app.adjSource
15144                    + " target=" + app.adjTarget);
15145        }
15146
15147        return app.curRawAdj;
15148    }
15149
15150    /**
15151     * Schedule PSS collection of a process.
15152     */
15153    void requestPssLocked(ProcessRecord proc, int procState) {
15154        if (mPendingPssProcesses.contains(proc)) {
15155            return;
15156        }
15157        if (mPendingPssProcesses.size() == 0) {
15158            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15159        }
15160        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15161        proc.pssProcState = procState;
15162        mPendingPssProcesses.add(proc);
15163    }
15164
15165    /**
15166     * Schedule PSS collection of all processes.
15167     */
15168    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15169        if (!always) {
15170            if (now < (mLastFullPssTime +
15171                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15172                return;
15173            }
15174        }
15175        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15176        mLastFullPssTime = now;
15177        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15178        mPendingPssProcesses.clear();
15179        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15180            ProcessRecord app = mLruProcesses.get(i);
15181            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15182                app.pssProcState = app.setProcState;
15183                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15184                        mSleeping, now);
15185                mPendingPssProcesses.add(app);
15186            }
15187        }
15188        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15189    }
15190
15191    /**
15192     * Ask a given process to GC right now.
15193     */
15194    final void performAppGcLocked(ProcessRecord app) {
15195        try {
15196            app.lastRequestedGc = SystemClock.uptimeMillis();
15197            if (app.thread != null) {
15198                if (app.reportLowMemory) {
15199                    app.reportLowMemory = false;
15200                    app.thread.scheduleLowMemory();
15201                } else {
15202                    app.thread.processInBackground();
15203                }
15204            }
15205        } catch (Exception e) {
15206            // whatever.
15207        }
15208    }
15209
15210    /**
15211     * Returns true if things are idle enough to perform GCs.
15212     */
15213    private final boolean canGcNowLocked() {
15214        boolean processingBroadcasts = false;
15215        for (BroadcastQueue q : mBroadcastQueues) {
15216            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15217                processingBroadcasts = true;
15218            }
15219        }
15220        return !processingBroadcasts
15221                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15222    }
15223
15224    /**
15225     * Perform GCs on all processes that are waiting for it, but only
15226     * if things are idle.
15227     */
15228    final void performAppGcsLocked() {
15229        final int N = mProcessesToGc.size();
15230        if (N <= 0) {
15231            return;
15232        }
15233        if (canGcNowLocked()) {
15234            while (mProcessesToGc.size() > 0) {
15235                ProcessRecord proc = mProcessesToGc.remove(0);
15236                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15237                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15238                            <= SystemClock.uptimeMillis()) {
15239                        // To avoid spamming the system, we will GC processes one
15240                        // at a time, waiting a few seconds between each.
15241                        performAppGcLocked(proc);
15242                        scheduleAppGcsLocked();
15243                        return;
15244                    } else {
15245                        // It hasn't been long enough since we last GCed this
15246                        // process...  put it in the list to wait for its time.
15247                        addProcessToGcListLocked(proc);
15248                        break;
15249                    }
15250                }
15251            }
15252
15253            scheduleAppGcsLocked();
15254        }
15255    }
15256
15257    /**
15258     * If all looks good, perform GCs on all processes waiting for them.
15259     */
15260    final void performAppGcsIfAppropriateLocked() {
15261        if (canGcNowLocked()) {
15262            performAppGcsLocked();
15263            return;
15264        }
15265        // Still not idle, wait some more.
15266        scheduleAppGcsLocked();
15267    }
15268
15269    /**
15270     * Schedule the execution of all pending app GCs.
15271     */
15272    final void scheduleAppGcsLocked() {
15273        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15274
15275        if (mProcessesToGc.size() > 0) {
15276            // Schedule a GC for the time to the next process.
15277            ProcessRecord proc = mProcessesToGc.get(0);
15278            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15279
15280            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15281            long now = SystemClock.uptimeMillis();
15282            if (when < (now+GC_TIMEOUT)) {
15283                when = now + GC_TIMEOUT;
15284            }
15285            mHandler.sendMessageAtTime(msg, when);
15286        }
15287    }
15288
15289    /**
15290     * Add a process to the array of processes waiting to be GCed.  Keeps the
15291     * list in sorted order by the last GC time.  The process can't already be
15292     * on the list.
15293     */
15294    final void addProcessToGcListLocked(ProcessRecord proc) {
15295        boolean added = false;
15296        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15297            if (mProcessesToGc.get(i).lastRequestedGc <
15298                    proc.lastRequestedGc) {
15299                added = true;
15300                mProcessesToGc.add(i+1, proc);
15301                break;
15302            }
15303        }
15304        if (!added) {
15305            mProcessesToGc.add(0, proc);
15306        }
15307    }
15308
15309    /**
15310     * Set up to ask a process to GC itself.  This will either do it
15311     * immediately, or put it on the list of processes to gc the next
15312     * time things are idle.
15313     */
15314    final void scheduleAppGcLocked(ProcessRecord app) {
15315        long now = SystemClock.uptimeMillis();
15316        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15317            return;
15318        }
15319        if (!mProcessesToGc.contains(app)) {
15320            addProcessToGcListLocked(app);
15321            scheduleAppGcsLocked();
15322        }
15323    }
15324
15325    final void checkExcessivePowerUsageLocked(boolean doKills) {
15326        updateCpuStatsNow();
15327
15328        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15329        boolean doWakeKills = doKills;
15330        boolean doCpuKills = doKills;
15331        if (mLastPowerCheckRealtime == 0) {
15332            doWakeKills = false;
15333        }
15334        if (mLastPowerCheckUptime == 0) {
15335            doCpuKills = false;
15336        }
15337        if (stats.isScreenOn()) {
15338            doWakeKills = false;
15339        }
15340        final long curRealtime = SystemClock.elapsedRealtime();
15341        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15342        final long curUptime = SystemClock.uptimeMillis();
15343        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15344        mLastPowerCheckRealtime = curRealtime;
15345        mLastPowerCheckUptime = curUptime;
15346        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15347            doWakeKills = false;
15348        }
15349        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15350            doCpuKills = false;
15351        }
15352        int i = mLruProcesses.size();
15353        while (i > 0) {
15354            i--;
15355            ProcessRecord app = mLruProcesses.get(i);
15356            if (!app.keeping) {
15357                long wtime;
15358                synchronized (stats) {
15359                    wtime = stats.getProcessWakeTime(app.info.uid,
15360                            app.pid, curRealtime);
15361                }
15362                long wtimeUsed = wtime - app.lastWakeTime;
15363                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15364                if (DEBUG_POWER) {
15365                    StringBuilder sb = new StringBuilder(128);
15366                    sb.append("Wake for ");
15367                    app.toShortString(sb);
15368                    sb.append(": over ");
15369                    TimeUtils.formatDuration(realtimeSince, sb);
15370                    sb.append(" used ");
15371                    TimeUtils.formatDuration(wtimeUsed, sb);
15372                    sb.append(" (");
15373                    sb.append((wtimeUsed*100)/realtimeSince);
15374                    sb.append("%)");
15375                    Slog.i(TAG, sb.toString());
15376                    sb.setLength(0);
15377                    sb.append("CPU for ");
15378                    app.toShortString(sb);
15379                    sb.append(": over ");
15380                    TimeUtils.formatDuration(uptimeSince, sb);
15381                    sb.append(" used ");
15382                    TimeUtils.formatDuration(cputimeUsed, sb);
15383                    sb.append(" (");
15384                    sb.append((cputimeUsed*100)/uptimeSince);
15385                    sb.append("%)");
15386                    Slog.i(TAG, sb.toString());
15387                }
15388                // If a process has held a wake lock for more
15389                // than 50% of the time during this period,
15390                // that sounds bad.  Kill!
15391                if (doWakeKills && realtimeSince > 0
15392                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15393                    synchronized (stats) {
15394                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15395                                realtimeSince, wtimeUsed);
15396                    }
15397                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15398                            + " during " + realtimeSince);
15399                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15400                } else if (doCpuKills && uptimeSince > 0
15401                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15402                    synchronized (stats) {
15403                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15404                                uptimeSince, cputimeUsed);
15405                    }
15406                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15407                            + " during " + uptimeSince);
15408                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15409                } else {
15410                    app.lastWakeTime = wtime;
15411                    app.lastCpuTime = app.curCpuTime;
15412                }
15413            }
15414        }
15415    }
15416
15417    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15418            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15419        boolean success = true;
15420
15421        if (app.curRawAdj != app.setRawAdj) {
15422            if (wasKeeping && !app.keeping) {
15423                // This app is no longer something we want to keep.  Note
15424                // its current wake lock time to later know to kill it if
15425                // it is not behaving well.
15426                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15427                synchronized (stats) {
15428                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15429                            app.pid, SystemClock.elapsedRealtime());
15430                }
15431                app.lastCpuTime = app.curCpuTime;
15432            }
15433
15434            app.setRawAdj = app.curRawAdj;
15435        }
15436
15437        if (app.curAdj != app.setAdj) {
15438            ProcessList.setOomAdj(app.pid, app.curAdj);
15439            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15440                TAG, "Set " + app.pid + " " + app.processName +
15441                " adj " + app.curAdj + ": " + app.adjType);
15442            app.setAdj = app.curAdj;
15443        }
15444
15445        if (app.setSchedGroup != app.curSchedGroup) {
15446            app.setSchedGroup = app.curSchedGroup;
15447            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15448                    "Setting process group of " + app.processName
15449                    + " to " + app.curSchedGroup);
15450            if (app.waitingToKill != null &&
15451                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15452                killUnneededProcessLocked(app, app.waitingToKill);
15453                success = false;
15454            } else {
15455                if (true) {
15456                    long oldId = Binder.clearCallingIdentity();
15457                    try {
15458                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15459                    } catch (Exception e) {
15460                        Slog.w(TAG, "Failed setting process group of " + app.pid
15461                                + " to " + app.curSchedGroup);
15462                        e.printStackTrace();
15463                    } finally {
15464                        Binder.restoreCallingIdentity(oldId);
15465                    }
15466                } else {
15467                    if (app.thread != null) {
15468                        try {
15469                            app.thread.setSchedulingGroup(app.curSchedGroup);
15470                        } catch (RemoteException e) {
15471                        }
15472                    }
15473                }
15474                Process.setSwappiness(app.pid,
15475                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15476            }
15477        }
15478        if (app.repProcState != app.curProcState) {
15479            app.repProcState = app.curProcState;
15480            if (!reportingProcessState && app.thread != null) {
15481                try {
15482                    if (false) {
15483                        //RuntimeException h = new RuntimeException("here");
15484                        Slog.i(TAG, "Sending new process state " + app.repProcState
15485                                + " to " + app /*, h*/);
15486                    }
15487                    app.thread.setProcessState(app.repProcState);
15488                } catch (RemoteException e) {
15489                }
15490            }
15491        }
15492        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15493                app.setProcState)) {
15494            app.lastStateTime = now;
15495            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15496                    mSleeping, now);
15497            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15498                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15499                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15500                    + (app.nextPssTime-now) + ": " + app);
15501        } else {
15502            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15503                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15504                requestPssLocked(app, app.setProcState);
15505                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15506                        mSleeping, now);
15507            } else if (false && DEBUG_PSS) {
15508                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15509            }
15510        }
15511        if (app.setProcState != app.curProcState) {
15512            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15513                    "Proc state change of " + app.processName
15514                    + " to " + app.curProcState);
15515            app.setProcState = app.curProcState;
15516            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15517                app.notCachedSinceIdle = false;
15518            }
15519            if (!doingAll) {
15520                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15521            } else {
15522                app.procStateChanged = true;
15523            }
15524        }
15525        return success;
15526    }
15527
15528    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15529        if (proc.thread != null && proc.baseProcessTracker != null) {
15530            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15531        }
15532    }
15533
15534    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15535            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15536        if (app.thread == null) {
15537            return false;
15538        }
15539
15540        final boolean wasKeeping = app.keeping;
15541
15542        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15543
15544        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15545                reportingProcessState, now);
15546    }
15547
15548    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15549            boolean oomAdj) {
15550        if (isForeground != proc.foregroundServices) {
15551            proc.foregroundServices = isForeground;
15552            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15553                    proc.info.uid);
15554            if (isForeground) {
15555                if (curProcs == null) {
15556                    curProcs = new ArrayList<ProcessRecord>();
15557                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15558                }
15559                if (!curProcs.contains(proc)) {
15560                    curProcs.add(proc);
15561                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15562                            proc.info.packageName, proc.info.uid);
15563                }
15564            } else {
15565                if (curProcs != null) {
15566                    if (curProcs.remove(proc)) {
15567                        mBatteryStatsService.noteEvent(
15568                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15569                                proc.info.packageName, proc.info.uid);
15570                        if (curProcs.size() <= 0) {
15571                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15572                        }
15573                    }
15574                }
15575            }
15576            if (oomAdj) {
15577                updateOomAdjLocked();
15578            }
15579        }
15580    }
15581
15582    private final ActivityRecord resumedAppLocked() {
15583        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15584        String pkg;
15585        int uid;
15586        if (act != null && !act.sleeping) {
15587            pkg = act.packageName;
15588            uid = act.info.applicationInfo.uid;
15589        } else {
15590            pkg = null;
15591            uid = -1;
15592        }
15593        // Has the UID or resumed package name changed?
15594        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15595                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15596            if (mCurResumedPackage != null) {
15597                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15598                        mCurResumedPackage, mCurResumedUid);
15599            }
15600            mCurResumedPackage = pkg;
15601            mCurResumedUid = uid;
15602            if (mCurResumedPackage != null) {
15603                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15604                        mCurResumedPackage, mCurResumedUid);
15605            }
15606        }
15607        return act;
15608    }
15609
15610    final boolean updateOomAdjLocked(ProcessRecord app) {
15611        return updateOomAdjLocked(app, false);
15612    }
15613
15614    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15615        final ActivityRecord TOP_ACT = resumedAppLocked();
15616        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15617        final boolean wasCached = app.cached;
15618
15619        mAdjSeq++;
15620
15621        // This is the desired cached adjusment we want to tell it to use.
15622        // If our app is currently cached, we know it, and that is it.  Otherwise,
15623        // we don't know it yet, and it needs to now be cached we will then
15624        // need to do a complete oom adj.
15625        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15626                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15627        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15628                SystemClock.uptimeMillis());
15629        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15630            // Changed to/from cached state, so apps after it in the LRU
15631            // list may also be changed.
15632            updateOomAdjLocked();
15633        }
15634        return success;
15635    }
15636
15637    final void updateOomAdjLocked() {
15638        final ActivityRecord TOP_ACT = resumedAppLocked();
15639        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15640        final long now = SystemClock.uptimeMillis();
15641        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15642        final int N = mLruProcesses.size();
15643
15644        if (false) {
15645            RuntimeException e = new RuntimeException();
15646            e.fillInStackTrace();
15647            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15648        }
15649
15650        mAdjSeq++;
15651        mNewNumServiceProcs = 0;
15652        mNewNumAServiceProcs = 0;
15653
15654        final int emptyProcessLimit;
15655        final int cachedProcessLimit;
15656        if (mProcessLimit <= 0) {
15657            emptyProcessLimit = cachedProcessLimit = 0;
15658        } else if (mProcessLimit == 1) {
15659            emptyProcessLimit = 1;
15660            cachedProcessLimit = 0;
15661        } else {
15662            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15663            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15664        }
15665
15666        // Let's determine how many processes we have running vs.
15667        // how many slots we have for background processes; we may want
15668        // to put multiple processes in a slot of there are enough of
15669        // them.
15670        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15671                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15672        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15673        if (numEmptyProcs > cachedProcessLimit) {
15674            // If there are more empty processes than our limit on cached
15675            // processes, then use the cached process limit for the factor.
15676            // This ensures that the really old empty processes get pushed
15677            // down to the bottom, so if we are running low on memory we will
15678            // have a better chance at keeping around more cached processes
15679            // instead of a gazillion empty processes.
15680            numEmptyProcs = cachedProcessLimit;
15681        }
15682        int emptyFactor = numEmptyProcs/numSlots;
15683        if (emptyFactor < 1) emptyFactor = 1;
15684        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15685        if (cachedFactor < 1) cachedFactor = 1;
15686        int stepCached = 0;
15687        int stepEmpty = 0;
15688        int numCached = 0;
15689        int numEmpty = 0;
15690        int numTrimming = 0;
15691
15692        mNumNonCachedProcs = 0;
15693        mNumCachedHiddenProcs = 0;
15694
15695        // First update the OOM adjustment for each of the
15696        // application processes based on their current state.
15697        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15698        int nextCachedAdj = curCachedAdj+1;
15699        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15700        int nextEmptyAdj = curEmptyAdj+2;
15701        for (int i=N-1; i>=0; i--) {
15702            ProcessRecord app = mLruProcesses.get(i);
15703            if (!app.killedByAm && app.thread != null) {
15704                app.procStateChanged = false;
15705                final boolean wasKeeping = app.keeping;
15706                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15707
15708                // If we haven't yet assigned the final cached adj
15709                // to the process, do that now.
15710                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15711                    switch (app.curProcState) {
15712                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15713                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15714                            // This process is a cached process holding activities...
15715                            // assign it the next cached value for that type, and then
15716                            // step that cached level.
15717                            app.curRawAdj = curCachedAdj;
15718                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15719                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15720                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15721                                    + ")");
15722                            if (curCachedAdj != nextCachedAdj) {
15723                                stepCached++;
15724                                if (stepCached >= cachedFactor) {
15725                                    stepCached = 0;
15726                                    curCachedAdj = nextCachedAdj;
15727                                    nextCachedAdj += 2;
15728                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15729                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15730                                    }
15731                                }
15732                            }
15733                            break;
15734                        default:
15735                            // For everything else, assign next empty cached process
15736                            // level and bump that up.  Note that this means that
15737                            // long-running services that have dropped down to the
15738                            // cached level will be treated as empty (since their process
15739                            // state is still as a service), which is what we want.
15740                            app.curRawAdj = curEmptyAdj;
15741                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15742                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15743                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15744                                    + ")");
15745                            if (curEmptyAdj != nextEmptyAdj) {
15746                                stepEmpty++;
15747                                if (stepEmpty >= emptyFactor) {
15748                                    stepEmpty = 0;
15749                                    curEmptyAdj = nextEmptyAdj;
15750                                    nextEmptyAdj += 2;
15751                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15752                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15753                                    }
15754                                }
15755                            }
15756                            break;
15757                    }
15758                }
15759
15760                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15761
15762                // Count the number of process types.
15763                switch (app.curProcState) {
15764                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15765                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15766                        mNumCachedHiddenProcs++;
15767                        numCached++;
15768                        if (numCached > cachedProcessLimit) {
15769                            killUnneededProcessLocked(app, "cached #" + numCached);
15770                        }
15771                        break;
15772                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15773                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15774                                && app.lastActivityTime < oldTime) {
15775                            killUnneededProcessLocked(app, "empty for "
15776                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15777                                    / 1000) + "s");
15778                        } else {
15779                            numEmpty++;
15780                            if (numEmpty > emptyProcessLimit) {
15781                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15782                            }
15783                        }
15784                        break;
15785                    default:
15786                        mNumNonCachedProcs++;
15787                        break;
15788                }
15789
15790                if (app.isolated && app.services.size() <= 0) {
15791                    // If this is an isolated process, and there are no
15792                    // services running in it, then the process is no longer
15793                    // needed.  We agressively kill these because we can by
15794                    // definition not re-use the same process again, and it is
15795                    // good to avoid having whatever code was running in them
15796                    // left sitting around after no longer needed.
15797                    killUnneededProcessLocked(app, "isolated not needed");
15798                }
15799
15800                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15801                        && !app.killedByAm) {
15802                    numTrimming++;
15803                }
15804            }
15805        }
15806
15807        mNumServiceProcs = mNewNumServiceProcs;
15808
15809        // Now determine the memory trimming level of background processes.
15810        // Unfortunately we need to start at the back of the list to do this
15811        // properly.  We only do this if the number of background apps we
15812        // are managing to keep around is less than half the maximum we desire;
15813        // if we are keeping a good number around, we'll let them use whatever
15814        // memory they want.
15815        final int numCachedAndEmpty = numCached + numEmpty;
15816        int memFactor;
15817        if (numCached <= ProcessList.TRIM_CACHED_APPS
15818                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15819            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15820                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15821            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15822                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15823            } else {
15824                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15825            }
15826        } else {
15827            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15828        }
15829        // We always allow the memory level to go up (better).  We only allow it to go
15830        // down if we are in a state where that is allowed, *and* the total number of processes
15831        // has gone down since last time.
15832        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15833                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15834                + " last=" + mLastNumProcesses);
15835        if (memFactor > mLastMemoryLevel) {
15836            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15837                memFactor = mLastMemoryLevel;
15838                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15839            }
15840        }
15841        mLastMemoryLevel = memFactor;
15842        mLastNumProcesses = mLruProcesses.size();
15843        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15844        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15845        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15846            if (mLowRamStartTime == 0) {
15847                mLowRamStartTime = now;
15848            }
15849            int step = 0;
15850            int fgTrimLevel;
15851            switch (memFactor) {
15852                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15853                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15854                    break;
15855                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15856                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15857                    break;
15858                default:
15859                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15860                    break;
15861            }
15862            int factor = numTrimming/3;
15863            int minFactor = 2;
15864            if (mHomeProcess != null) minFactor++;
15865            if (mPreviousProcess != null) minFactor++;
15866            if (factor < minFactor) factor = minFactor;
15867            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15868            for (int i=N-1; i>=0; i--) {
15869                ProcessRecord app = mLruProcesses.get(i);
15870                if (allChanged || app.procStateChanged) {
15871                    setProcessTrackerState(app, trackerMemFactor, now);
15872                    app.procStateChanged = false;
15873                }
15874                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15875                        && !app.killedByAm) {
15876                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15877                        try {
15878                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15879                                    "Trimming memory of " + app.processName
15880                                    + " to " + curLevel);
15881                            app.thread.scheduleTrimMemory(curLevel);
15882                        } catch (RemoteException e) {
15883                        }
15884                        if (false) {
15885                            // For now we won't do this; our memory trimming seems
15886                            // to be good enough at this point that destroying
15887                            // activities causes more harm than good.
15888                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15889                                    && app != mHomeProcess && app != mPreviousProcess) {
15890                                // Need to do this on its own message because the stack may not
15891                                // be in a consistent state at this point.
15892                                // For these apps we will also finish their activities
15893                                // to help them free memory.
15894                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15895                            }
15896                        }
15897                    }
15898                    app.trimMemoryLevel = curLevel;
15899                    step++;
15900                    if (step >= factor) {
15901                        step = 0;
15902                        switch (curLevel) {
15903                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15904                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15905                                break;
15906                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15907                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15908                                break;
15909                        }
15910                    }
15911                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15912                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15913                            && app.thread != null) {
15914                        try {
15915                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15916                                    "Trimming memory of heavy-weight " + app.processName
15917                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15918                            app.thread.scheduleTrimMemory(
15919                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15920                        } catch (RemoteException e) {
15921                        }
15922                    }
15923                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15924                } else {
15925                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15926                            || app.systemNoUi) && app.pendingUiClean) {
15927                        // If this application is now in the background and it
15928                        // had done UI, then give it the special trim level to
15929                        // have it free UI resources.
15930                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15931                        if (app.trimMemoryLevel < level && app.thread != null) {
15932                            try {
15933                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15934                                        "Trimming memory of bg-ui " + app.processName
15935                                        + " to " + level);
15936                                app.thread.scheduleTrimMemory(level);
15937                            } catch (RemoteException e) {
15938                            }
15939                        }
15940                        app.pendingUiClean = false;
15941                    }
15942                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15943                        try {
15944                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15945                                    "Trimming memory of fg " + app.processName
15946                                    + " to " + fgTrimLevel);
15947                            app.thread.scheduleTrimMemory(fgTrimLevel);
15948                        } catch (RemoteException e) {
15949                        }
15950                    }
15951                    app.trimMemoryLevel = fgTrimLevel;
15952                }
15953            }
15954        } else {
15955            if (mLowRamStartTime != 0) {
15956                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15957                mLowRamStartTime = 0;
15958            }
15959            for (int i=N-1; i>=0; i--) {
15960                ProcessRecord app = mLruProcesses.get(i);
15961                if (allChanged || app.procStateChanged) {
15962                    setProcessTrackerState(app, trackerMemFactor, now);
15963                    app.procStateChanged = false;
15964                }
15965                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15966                        || app.systemNoUi) && app.pendingUiClean) {
15967                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15968                            && app.thread != null) {
15969                        try {
15970                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15971                                    "Trimming memory of ui hidden " + app.processName
15972                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15973                            app.thread.scheduleTrimMemory(
15974                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15975                        } catch (RemoteException e) {
15976                        }
15977                    }
15978                    app.pendingUiClean = false;
15979                }
15980                app.trimMemoryLevel = 0;
15981            }
15982        }
15983
15984        if (mAlwaysFinishActivities) {
15985            // Need to do this on its own message because the stack may not
15986            // be in a consistent state at this point.
15987            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15988        }
15989
15990        if (allChanged) {
15991            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15992        }
15993
15994        if (mProcessStats.shouldWriteNowLocked(now)) {
15995            mHandler.post(new Runnable() {
15996                @Override public void run() {
15997                    synchronized (ActivityManagerService.this) {
15998                        mProcessStats.writeStateAsyncLocked();
15999                    }
16000                }
16001            });
16002        }
16003
16004        if (DEBUG_OOM_ADJ) {
16005            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16006        }
16007    }
16008
16009    final void trimApplications() {
16010        synchronized (this) {
16011            int i;
16012
16013            // First remove any unused application processes whose package
16014            // has been removed.
16015            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16016                final ProcessRecord app = mRemovedProcesses.get(i);
16017                if (app.activities.size() == 0
16018                        && app.curReceiver == null && app.services.size() == 0) {
16019                    Slog.i(
16020                        TAG, "Exiting empty application process "
16021                        + app.processName + " ("
16022                        + (app.thread != null ? app.thread.asBinder() : null)
16023                        + ")\n");
16024                    if (app.pid > 0 && app.pid != MY_PID) {
16025                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16026                                app.processName, app.setAdj, "empty");
16027                        app.killedByAm = true;
16028                        Process.killProcessQuiet(app.pid);
16029                    } else {
16030                        try {
16031                            app.thread.scheduleExit();
16032                        } catch (Exception e) {
16033                            // Ignore exceptions.
16034                        }
16035                    }
16036                    cleanUpApplicationRecordLocked(app, false, true, -1);
16037                    mRemovedProcesses.remove(i);
16038
16039                    if (app.persistent) {
16040                        if (app.persistent) {
16041                            addAppLocked(app.info, false);
16042                        }
16043                    }
16044                }
16045            }
16046
16047            // Now update the oom adj for all processes.
16048            updateOomAdjLocked();
16049        }
16050    }
16051
16052    /** This method sends the specified signal to each of the persistent apps */
16053    public void signalPersistentProcesses(int sig) throws RemoteException {
16054        if (sig != Process.SIGNAL_USR1) {
16055            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16056        }
16057
16058        synchronized (this) {
16059            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16060                    != PackageManager.PERMISSION_GRANTED) {
16061                throw new SecurityException("Requires permission "
16062                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16063            }
16064
16065            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16066                ProcessRecord r = mLruProcesses.get(i);
16067                if (r.thread != null && r.persistent) {
16068                    Process.sendSignal(r.pid, sig);
16069                }
16070            }
16071        }
16072    }
16073
16074    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16075        if (proc == null || proc == mProfileProc) {
16076            proc = mProfileProc;
16077            path = mProfileFile;
16078            profileType = mProfileType;
16079            clearProfilerLocked();
16080        }
16081        if (proc == null) {
16082            return;
16083        }
16084        try {
16085            proc.thread.profilerControl(false, path, null, profileType);
16086        } catch (RemoteException e) {
16087            throw new IllegalStateException("Process disappeared");
16088        }
16089    }
16090
16091    private void clearProfilerLocked() {
16092        if (mProfileFd != null) {
16093            try {
16094                mProfileFd.close();
16095            } catch (IOException e) {
16096            }
16097        }
16098        mProfileApp = null;
16099        mProfileProc = null;
16100        mProfileFile = null;
16101        mProfileType = 0;
16102        mAutoStopProfiler = false;
16103    }
16104
16105    public boolean profileControl(String process, int userId, boolean start,
16106            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16107
16108        try {
16109            synchronized (this) {
16110                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16111                // its own permission.
16112                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16113                        != PackageManager.PERMISSION_GRANTED) {
16114                    throw new SecurityException("Requires permission "
16115                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16116                }
16117
16118                if (start && fd == null) {
16119                    throw new IllegalArgumentException("null fd");
16120                }
16121
16122                ProcessRecord proc = null;
16123                if (process != null) {
16124                    proc = findProcessLocked(process, userId, "profileControl");
16125                }
16126
16127                if (start && (proc == null || proc.thread == null)) {
16128                    throw new IllegalArgumentException("Unknown process: " + process);
16129                }
16130
16131                if (start) {
16132                    stopProfilerLocked(null, null, 0);
16133                    setProfileApp(proc.info, proc.processName, path, fd, false);
16134                    mProfileProc = proc;
16135                    mProfileType = profileType;
16136                    try {
16137                        fd = fd.dup();
16138                    } catch (IOException e) {
16139                        fd = null;
16140                    }
16141                    proc.thread.profilerControl(start, path, fd, profileType);
16142                    fd = null;
16143                    mProfileFd = null;
16144                } else {
16145                    stopProfilerLocked(proc, path, profileType);
16146                    if (fd != null) {
16147                        try {
16148                            fd.close();
16149                        } catch (IOException e) {
16150                        }
16151                    }
16152                }
16153
16154                return true;
16155            }
16156        } catch (RemoteException e) {
16157            throw new IllegalStateException("Process disappeared");
16158        } finally {
16159            if (fd != null) {
16160                try {
16161                    fd.close();
16162                } catch (IOException e) {
16163                }
16164            }
16165        }
16166    }
16167
16168    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16169        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16170                userId, true, true, callName, null);
16171        ProcessRecord proc = null;
16172        try {
16173            int pid = Integer.parseInt(process);
16174            synchronized (mPidsSelfLocked) {
16175                proc = mPidsSelfLocked.get(pid);
16176            }
16177        } catch (NumberFormatException e) {
16178        }
16179
16180        if (proc == null) {
16181            ArrayMap<String, SparseArray<ProcessRecord>> all
16182                    = mProcessNames.getMap();
16183            SparseArray<ProcessRecord> procs = all.get(process);
16184            if (procs != null && procs.size() > 0) {
16185                proc = procs.valueAt(0);
16186                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16187                    for (int i=1; i<procs.size(); i++) {
16188                        ProcessRecord thisProc = procs.valueAt(i);
16189                        if (thisProc.userId == userId) {
16190                            proc = thisProc;
16191                            break;
16192                        }
16193                    }
16194                }
16195            }
16196        }
16197
16198        return proc;
16199    }
16200
16201    public boolean dumpHeap(String process, int userId, boolean managed,
16202            String path, ParcelFileDescriptor fd) throws RemoteException {
16203
16204        try {
16205            synchronized (this) {
16206                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16207                // its own permission (same as profileControl).
16208                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16209                        != PackageManager.PERMISSION_GRANTED) {
16210                    throw new SecurityException("Requires permission "
16211                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16212                }
16213
16214                if (fd == null) {
16215                    throw new IllegalArgumentException("null fd");
16216                }
16217
16218                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16219                if (proc == null || proc.thread == null) {
16220                    throw new IllegalArgumentException("Unknown process: " + process);
16221                }
16222
16223                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16224                if (!isDebuggable) {
16225                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16226                        throw new SecurityException("Process not debuggable: " + proc);
16227                    }
16228                }
16229
16230                proc.thread.dumpHeap(managed, path, fd);
16231                fd = null;
16232                return true;
16233            }
16234        } catch (RemoteException e) {
16235            throw new IllegalStateException("Process disappeared");
16236        } finally {
16237            if (fd != null) {
16238                try {
16239                    fd.close();
16240                } catch (IOException e) {
16241                }
16242            }
16243        }
16244    }
16245
16246    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16247    public void monitor() {
16248        synchronized (this) { }
16249    }
16250
16251    void onCoreSettingsChange(Bundle settings) {
16252        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16253            ProcessRecord processRecord = mLruProcesses.get(i);
16254            try {
16255                if (processRecord.thread != null) {
16256                    processRecord.thread.setCoreSettings(settings);
16257                }
16258            } catch (RemoteException re) {
16259                /* ignore */
16260            }
16261        }
16262    }
16263
16264    // Multi-user methods
16265
16266    /**
16267     * Start user, if its not already running, but don't bring it to foreground.
16268     */
16269    @Override
16270    public boolean startUserInBackground(final int userId) {
16271        return startUser(userId, /* foreground */ false);
16272    }
16273
16274    /**
16275     * Refreshes the list of users related to the current user when either a
16276     * user switch happens or when a new related user is started in the
16277     * background.
16278     */
16279    private void updateRelatedUserIdsLocked() {
16280        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16281        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
16282        for (int i = 0; i < relatedUserIds.length; i++) {
16283            relatedUserIds[i] = relatedUsers.get(i).id;
16284        }
16285        mRelatedUserIds = relatedUserIds;
16286    }
16287
16288    private Set getRelatedUsersLocked(int userId) {
16289        Set userIds = new HashSet<Integer>();
16290        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId);
16291        for (UserInfo user : relatedUsers) {
16292            userIds.add(Integer.valueOf(user.id));
16293        }
16294        return userIds;
16295    }
16296
16297    @Override
16298    public boolean switchUser(final int userId) {
16299        return startUser(userId, /* foregound */ true);
16300    }
16301
16302    private boolean startUser(final int userId, boolean foreground) {
16303        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16304                != PackageManager.PERMISSION_GRANTED) {
16305            String msg = "Permission Denial: switchUser() from pid="
16306                    + Binder.getCallingPid()
16307                    + ", uid=" + Binder.getCallingUid()
16308                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16309            Slog.w(TAG, msg);
16310            throw new SecurityException(msg);
16311        }
16312
16313        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16314
16315        final long ident = Binder.clearCallingIdentity();
16316        try {
16317            synchronized (this) {
16318                final int oldUserId = mCurrentUserId;
16319                if (oldUserId == userId) {
16320                    return true;
16321                }
16322
16323                mStackSupervisor.setLockTaskModeLocked(null);
16324
16325                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16326                if (userInfo == null) {
16327                    Slog.w(TAG, "No user info for user #" + userId);
16328                    return false;
16329                }
16330
16331                if (foreground) {
16332                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16333                            R.anim.screen_user_enter);
16334                }
16335
16336                boolean needStart = false;
16337
16338                // If the user we are switching to is not currently started, then
16339                // we need to start it now.
16340                if (mStartedUsers.get(userId) == null) {
16341                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16342                    updateStartedUserArrayLocked();
16343                    needStart = true;
16344                }
16345
16346                final Integer userIdInt = Integer.valueOf(userId);
16347                mUserLru.remove(userIdInt);
16348                mUserLru.add(userIdInt);
16349
16350                if (foreground) {
16351                    mCurrentUserId = userId;
16352                    updateRelatedUserIdsLocked();
16353                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
16354                    // Once the internal notion of the active user has switched, we lock the device
16355                    // with the option to show the user switcher on the keyguard.
16356                    mWindowManager.lockNow(null);
16357                } else {
16358                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16359                    updateRelatedUserIdsLocked();
16360                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
16361                    mUserLru.remove(currentUserIdInt);
16362                    mUserLru.add(currentUserIdInt);
16363                }
16364
16365                final UserStartedState uss = mStartedUsers.get(userId);
16366
16367                // Make sure user is in the started state.  If it is currently
16368                // stopping, we need to knock that off.
16369                if (uss.mState == UserStartedState.STATE_STOPPING) {
16370                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16371                    // so we can just fairly silently bring the user back from
16372                    // the almost-dead.
16373                    uss.mState = UserStartedState.STATE_RUNNING;
16374                    updateStartedUserArrayLocked();
16375                    needStart = true;
16376                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16377                    // This means ACTION_SHUTDOWN has been sent, so we will
16378                    // need to treat this as a new boot of the user.
16379                    uss.mState = UserStartedState.STATE_BOOTING;
16380                    updateStartedUserArrayLocked();
16381                    needStart = true;
16382                }
16383
16384                if (foreground) {
16385                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16386                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16387                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16388                            oldUserId, userId, uss));
16389                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16390                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16391                }
16392
16393                if (needStart) {
16394                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16395                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16396                            | Intent.FLAG_RECEIVER_FOREGROUND);
16397                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16398                    broadcastIntentLocked(null, null, intent,
16399                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16400                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16401                }
16402
16403                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16404                    if (userId != 0) {
16405                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16406                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16407                        broadcastIntentLocked(null, null, intent, null,
16408                                new IIntentReceiver.Stub() {
16409                                    public void performReceive(Intent intent, int resultCode,
16410                                            String data, Bundle extras, boolean ordered,
16411                                            boolean sticky, int sendingUser) {
16412                                        userInitialized(uss, userId);
16413                                    }
16414                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16415                                true, false, MY_PID, Process.SYSTEM_UID,
16416                                userId);
16417                        uss.initializing = true;
16418                    } else {
16419                        getUserManagerLocked().makeInitialized(userInfo.id);
16420                    }
16421                }
16422
16423                if (foreground) {
16424                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16425                    if (homeInFront) {
16426                        startHomeActivityLocked(userId);
16427                    } else {
16428                        mStackSupervisor.resumeTopActivitiesLocked();
16429                    }
16430                    EventLogTags.writeAmSwitchUser(userId);
16431                    getUserManagerLocked().userForeground(userId);
16432                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16433                }
16434
16435                if (needStart) {
16436                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16437                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16438                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16439                    broadcastIntentLocked(null, null, intent,
16440                            null, new IIntentReceiver.Stub() {
16441                                @Override
16442                                public void performReceive(Intent intent, int resultCode, String data,
16443                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16444                                        throws RemoteException {
16445                                }
16446                            }, 0, null, null,
16447                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16448                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16449                }
16450            }
16451        } finally {
16452            Binder.restoreCallingIdentity(ident);
16453        }
16454
16455        return true;
16456    }
16457
16458    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16459        long ident = Binder.clearCallingIdentity();
16460        try {
16461            Intent intent;
16462            if (oldUserId >= 0) {
16463                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16464                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16465                        | Intent.FLAG_RECEIVER_FOREGROUND);
16466                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16467                broadcastIntentLocked(null, null, intent,
16468                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16469                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16470            }
16471            if (newUserId >= 0) {
16472                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16473                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16474                        | Intent.FLAG_RECEIVER_FOREGROUND);
16475                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16476                broadcastIntentLocked(null, null, intent,
16477                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16478                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16479                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16480                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16481                        | Intent.FLAG_RECEIVER_FOREGROUND);
16482                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16483                broadcastIntentLocked(null, null, intent,
16484                        null, null, 0, null, null,
16485                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16486                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16487            }
16488        } finally {
16489            Binder.restoreCallingIdentity(ident);
16490        }
16491    }
16492
16493    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16494            final int newUserId) {
16495        final int N = mUserSwitchObservers.beginBroadcast();
16496        if (N > 0) {
16497            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16498                int mCount = 0;
16499                @Override
16500                public void sendResult(Bundle data) throws RemoteException {
16501                    synchronized (ActivityManagerService.this) {
16502                        if (mCurUserSwitchCallback == this) {
16503                            mCount++;
16504                            if (mCount == N) {
16505                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16506                            }
16507                        }
16508                    }
16509                }
16510            };
16511            synchronized (this) {
16512                uss.switching = true;
16513                mCurUserSwitchCallback = callback;
16514            }
16515            for (int i=0; i<N; i++) {
16516                try {
16517                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16518                            newUserId, callback);
16519                } catch (RemoteException e) {
16520                }
16521            }
16522        } else {
16523            synchronized (this) {
16524                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16525            }
16526        }
16527        mUserSwitchObservers.finishBroadcast();
16528    }
16529
16530    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16531        synchronized (this) {
16532            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16533            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16534        }
16535    }
16536
16537    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16538        mCurUserSwitchCallback = null;
16539        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16540        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16541                oldUserId, newUserId, uss));
16542    }
16543
16544    void userInitialized(UserStartedState uss, int newUserId) {
16545        completeSwitchAndInitalize(uss, newUserId, true, false);
16546    }
16547
16548    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16549        completeSwitchAndInitalize(uss, newUserId, false, true);
16550    }
16551
16552    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16553            boolean clearInitializing, boolean clearSwitching) {
16554        boolean unfrozen = false;
16555        synchronized (this) {
16556            if (clearInitializing) {
16557                uss.initializing = false;
16558                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16559            }
16560            if (clearSwitching) {
16561                uss.switching = false;
16562            }
16563            if (!uss.switching && !uss.initializing) {
16564                mWindowManager.stopFreezingScreen();
16565                unfrozen = true;
16566            }
16567        }
16568        if (unfrozen) {
16569            final int N = mUserSwitchObservers.beginBroadcast();
16570            for (int i=0; i<N; i++) {
16571                try {
16572                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16573                } catch (RemoteException e) {
16574                }
16575            }
16576            mUserSwitchObservers.finishBroadcast();
16577        }
16578    }
16579
16580    void scheduleStartRelatedUsersLocked() {
16581        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16582            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16583                    DateUtils.SECOND_IN_MILLIS);
16584        }
16585    }
16586
16587    void startRelatedUsersLocked() {
16588        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16589        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16590        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16591        for (UserInfo relatedUser : relatedUsers) {
16592            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16593                toStart.add(relatedUser);
16594            }
16595        }
16596        final int n = toStart.size();
16597        int i = 0;
16598        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16599            startUserInBackground(toStart.get(i).id);
16600        }
16601        if (i < n) {
16602            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16603        }
16604    }
16605
16606    void finishUserSwitch(UserStartedState uss) {
16607        synchronized (this) {
16608            if (uss.mState == UserStartedState.STATE_BOOTING
16609                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16610                uss.mState = UserStartedState.STATE_RUNNING;
16611                final int userId = uss.mHandle.getIdentifier();
16612                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16613                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16614                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16615                broadcastIntentLocked(null, null, intent,
16616                        null, null, 0, null, null,
16617                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16618                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16619            }
16620
16621            startRelatedUsersLocked();
16622
16623            int num = mUserLru.size();
16624            int i = 0;
16625            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16626                Integer oldUserId = mUserLru.get(i);
16627                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16628                if (oldUss == null) {
16629                    // Shouldn't happen, but be sane if it does.
16630                    mUserLru.remove(i);
16631                    num--;
16632                    continue;
16633                }
16634                if (oldUss.mState == UserStartedState.STATE_STOPPING
16635                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16636                    // This user is already stopping, doesn't count.
16637                    num--;
16638                    i++;
16639                    continue;
16640                }
16641                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16642                    // Owner and current can't be stopped, but count as running.
16643                    i++;
16644                    continue;
16645                }
16646                // This is a user to be stopped.
16647                stopUserLocked(oldUserId, null);
16648                num--;
16649                i++;
16650            }
16651        }
16652    }
16653
16654    @Override
16655    public int stopUser(final int userId, final IStopUserCallback callback) {
16656        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16657                != PackageManager.PERMISSION_GRANTED) {
16658            String msg = "Permission Denial: switchUser() from pid="
16659                    + Binder.getCallingPid()
16660                    + ", uid=" + Binder.getCallingUid()
16661                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16662            Slog.w(TAG, msg);
16663            throw new SecurityException(msg);
16664        }
16665        if (userId <= 0) {
16666            throw new IllegalArgumentException("Can't stop primary user " + userId);
16667        }
16668        synchronized (this) {
16669            return stopUserLocked(userId, callback);
16670        }
16671    }
16672
16673    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16674        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16675        if (mCurrentUserId == userId) {
16676            return ActivityManager.USER_OP_IS_CURRENT;
16677        }
16678
16679        final UserStartedState uss = mStartedUsers.get(userId);
16680        if (uss == null) {
16681            // User is not started, nothing to do...  but we do need to
16682            // callback if requested.
16683            if (callback != null) {
16684                mHandler.post(new Runnable() {
16685                    @Override
16686                    public void run() {
16687                        try {
16688                            callback.userStopped(userId);
16689                        } catch (RemoteException e) {
16690                        }
16691                    }
16692                });
16693            }
16694            return ActivityManager.USER_OP_SUCCESS;
16695        }
16696
16697        if (callback != null) {
16698            uss.mStopCallbacks.add(callback);
16699        }
16700
16701        if (uss.mState != UserStartedState.STATE_STOPPING
16702                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16703            uss.mState = UserStartedState.STATE_STOPPING;
16704            updateStartedUserArrayLocked();
16705
16706            long ident = Binder.clearCallingIdentity();
16707            try {
16708                // We are going to broadcast ACTION_USER_STOPPING and then
16709                // once that is done send a final ACTION_SHUTDOWN and then
16710                // stop the user.
16711                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16712                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16713                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16714                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16715                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16716                // This is the result receiver for the final shutdown broadcast.
16717                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16718                    @Override
16719                    public void performReceive(Intent intent, int resultCode, String data,
16720                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16721                        finishUserStop(uss);
16722                    }
16723                };
16724                // This is the result receiver for the initial stopping broadcast.
16725                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16726                    @Override
16727                    public void performReceive(Intent intent, int resultCode, String data,
16728                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16729                        // On to the next.
16730                        synchronized (ActivityManagerService.this) {
16731                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16732                                // Whoops, we are being started back up.  Abort, abort!
16733                                return;
16734                            }
16735                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16736                        }
16737                        broadcastIntentLocked(null, null, shutdownIntent,
16738                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16739                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16740                    }
16741                };
16742                // Kick things off.
16743                broadcastIntentLocked(null, null, stoppingIntent,
16744                        null, stoppingReceiver, 0, null, null,
16745                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16746                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16747            } finally {
16748                Binder.restoreCallingIdentity(ident);
16749            }
16750        }
16751
16752        return ActivityManager.USER_OP_SUCCESS;
16753    }
16754
16755    void finishUserStop(UserStartedState uss) {
16756        final int userId = uss.mHandle.getIdentifier();
16757        boolean stopped;
16758        ArrayList<IStopUserCallback> callbacks;
16759        synchronized (this) {
16760            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16761            if (mStartedUsers.get(userId) != uss) {
16762                stopped = false;
16763            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16764                stopped = false;
16765            } else {
16766                stopped = true;
16767                // User can no longer run.
16768                mStartedUsers.remove(userId);
16769                mUserLru.remove(Integer.valueOf(userId));
16770                updateStartedUserArrayLocked();
16771
16772                // Clean up all state and processes associated with the user.
16773                // Kill all the processes for the user.
16774                forceStopUserLocked(userId, "finish user");
16775            }
16776        }
16777
16778        for (int i=0; i<callbacks.size(); i++) {
16779            try {
16780                if (stopped) callbacks.get(i).userStopped(userId);
16781                else callbacks.get(i).userStopAborted(userId);
16782            } catch (RemoteException e) {
16783            }
16784        }
16785
16786        mStackSupervisor.removeUserLocked(userId);
16787    }
16788
16789    @Override
16790    public UserInfo getCurrentUser() {
16791        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16792                != PackageManager.PERMISSION_GRANTED) && (
16793                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16794                != PackageManager.PERMISSION_GRANTED)) {
16795            String msg = "Permission Denial: getCurrentUser() from pid="
16796                    + Binder.getCallingPid()
16797                    + ", uid=" + Binder.getCallingUid()
16798                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16799            Slog.w(TAG, msg);
16800            throw new SecurityException(msg);
16801        }
16802        synchronized (this) {
16803            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16804        }
16805    }
16806
16807    int getCurrentUserIdLocked() {
16808        return mCurrentUserId;
16809    }
16810
16811    @Override
16812    public boolean isUserRunning(int userId, boolean orStopped) {
16813        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16814                != PackageManager.PERMISSION_GRANTED) {
16815            String msg = "Permission Denial: isUserRunning() from pid="
16816                    + Binder.getCallingPid()
16817                    + ", uid=" + Binder.getCallingUid()
16818                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16819            Slog.w(TAG, msg);
16820            throw new SecurityException(msg);
16821        }
16822        synchronized (this) {
16823            return isUserRunningLocked(userId, orStopped);
16824        }
16825    }
16826
16827    boolean isUserRunningLocked(int userId, boolean orStopped) {
16828        UserStartedState state = mStartedUsers.get(userId);
16829        if (state == null) {
16830            return false;
16831        }
16832        if (orStopped) {
16833            return true;
16834        }
16835        return state.mState != UserStartedState.STATE_STOPPING
16836                && state.mState != UserStartedState.STATE_SHUTDOWN;
16837    }
16838
16839    @Override
16840    public int[] getRunningUserIds() {
16841        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16842                != PackageManager.PERMISSION_GRANTED) {
16843            String msg = "Permission Denial: isUserRunning() from pid="
16844                    + Binder.getCallingPid()
16845                    + ", uid=" + Binder.getCallingUid()
16846                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16847            Slog.w(TAG, msg);
16848            throw new SecurityException(msg);
16849        }
16850        synchronized (this) {
16851            return mStartedUserArray;
16852        }
16853    }
16854
16855    private void updateStartedUserArrayLocked() {
16856        int num = 0;
16857        for (int i=0; i<mStartedUsers.size();  i++) {
16858            UserStartedState uss = mStartedUsers.valueAt(i);
16859            // This list does not include stopping users.
16860            if (uss.mState != UserStartedState.STATE_STOPPING
16861                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16862                num++;
16863            }
16864        }
16865        mStartedUserArray = new int[num];
16866        num = 0;
16867        for (int i=0; i<mStartedUsers.size();  i++) {
16868            UserStartedState uss = mStartedUsers.valueAt(i);
16869            if (uss.mState != UserStartedState.STATE_STOPPING
16870                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16871                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16872                num++;
16873            }
16874        }
16875    }
16876
16877    @Override
16878    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16879        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16880                != PackageManager.PERMISSION_GRANTED) {
16881            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16882                    + Binder.getCallingPid()
16883                    + ", uid=" + Binder.getCallingUid()
16884                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16885            Slog.w(TAG, msg);
16886            throw new SecurityException(msg);
16887        }
16888
16889        mUserSwitchObservers.register(observer);
16890    }
16891
16892    @Override
16893    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16894        mUserSwitchObservers.unregister(observer);
16895    }
16896
16897    private boolean userExists(int userId) {
16898        if (userId == 0) {
16899            return true;
16900        }
16901        UserManagerService ums = getUserManagerLocked();
16902        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16903    }
16904
16905    int[] getUsersLocked() {
16906        UserManagerService ums = getUserManagerLocked();
16907        return ums != null ? ums.getUserIds() : new int[] { 0 };
16908    }
16909
16910    UserManagerService getUserManagerLocked() {
16911        if (mUserManager == null) {
16912            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16913            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16914        }
16915        return mUserManager;
16916    }
16917
16918    private int applyUserId(int uid, int userId) {
16919        return UserHandle.getUid(userId, uid);
16920    }
16921
16922    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16923        if (info == null) return null;
16924        ApplicationInfo newInfo = new ApplicationInfo(info);
16925        newInfo.uid = applyUserId(info.uid, userId);
16926        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16927                + info.packageName;
16928        return newInfo;
16929    }
16930
16931    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16932        if (aInfo == null
16933                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16934            return aInfo;
16935        }
16936
16937        ActivityInfo info = new ActivityInfo(aInfo);
16938        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16939        return info;
16940    }
16941}
16942