ActivityManagerService.java revision 303e1ff1fec8b240b587bb18b981247a99833aa8
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20import static com.android.internal.util.XmlUtils.readIntAttribute;
21import static com.android.internal.util.XmlUtils.readLongAttribute;
22import static com.android.internal.util.XmlUtils.writeIntAttribute;
23import static com.android.internal.util.XmlUtils.writeLongAttribute;
24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
26import static org.xmlpull.v1.XmlPullParser.START_TAG;
27
28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
29
30import android.app.AppOpsManager;
31import android.app.IActivityContainer;
32import android.app.IActivityContainerCallback;
33import android.appwidget.AppWidgetManager;
34import android.graphics.Rect;
35import android.os.BatteryStats;
36import android.util.ArrayMap;
37import com.android.internal.R;
38import com.android.internal.annotations.GuardedBy;
39import com.android.internal.app.IAppOpsService;
40import com.android.internal.app.ProcessMap;
41import com.android.internal.app.ProcessStats;
42import com.android.internal.os.BackgroundThread;
43import com.android.internal.os.BatteryStatsImpl;
44import com.android.internal.os.ProcessCpuTracker;
45import com.android.internal.os.TransferPipe;
46import com.android.internal.util.FastPrintWriter;
47import com.android.internal.util.FastXmlSerializer;
48import com.android.internal.util.MemInfoReader;
49import com.android.internal.util.Preconditions;
50import com.android.server.AppOpsService;
51import com.android.server.AttributeCache;
52import com.android.server.IntentResolver;
53import com.android.server.ServiceThread;
54import com.android.server.SystemService;
55import com.android.server.Watchdog;
56import com.android.server.am.ActivityStack.ActivityState;
57import com.android.server.firewall.IntentFirewall;
58import com.android.server.pm.UserManagerService;
59import com.android.server.wm.AppTransition;
60import com.android.server.wm.WindowManagerService;
61import com.google.android.collect.Lists;
62import com.google.android.collect.Maps;
63
64import dalvik.system.Zygote;
65
66import libcore.io.IoUtils;
67
68import org.xmlpull.v1.XmlPullParser;
69import org.xmlpull.v1.XmlPullParserException;
70import org.xmlpull.v1.XmlSerializer;
71
72import android.app.Activity;
73import android.app.ActivityManager;
74import android.app.ActivityManager.RunningTaskInfo;
75import android.app.ActivityManager.StackInfo;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.ApplicationErrorReport;
82import android.app.Dialog;
83import android.app.IActivityController;
84import android.app.IApplicationThread;
85import android.app.IInstrumentationWatcher;
86import android.app.INotificationManager;
87import android.app.IProcessObserver;
88import android.app.IServiceConnection;
89import android.app.IStopUserCallback;
90import android.app.IThumbnailReceiver;
91import android.app.IUiAutomationConnection;
92import android.app.IUserSwitchObserver;
93import android.app.Instrumentation;
94import android.app.Notification;
95import android.app.NotificationManager;
96import android.app.PendingIntent;
97import android.app.backup.IBackupManager;
98import android.content.ActivityNotFoundException;
99import android.content.BroadcastReceiver;
100import android.content.ClipData;
101import android.content.ComponentCallbacks2;
102import android.content.ComponentName;
103import android.content.ContentProvider;
104import android.content.ContentResolver;
105import android.content.Context;
106import android.content.DialogInterface;
107import android.content.IContentProvider;
108import android.content.IIntentReceiver;
109import android.content.IIntentSender;
110import android.content.Intent;
111import android.content.IntentFilter;
112import android.content.IntentSender;
113import android.content.pm.ActivityInfo;
114import android.content.pm.ApplicationInfo;
115import android.content.pm.ConfigurationInfo;
116import android.content.pm.IPackageDataObserver;
117import android.content.pm.IPackageManager;
118import android.content.pm.InstrumentationInfo;
119import android.content.pm.PackageInfo;
120import android.content.pm.PackageManager;
121import android.content.pm.ParceledListSlice;
122import android.content.pm.UserInfo;
123import android.content.pm.PackageManager.NameNotFoundException;
124import android.content.pm.PathPermission;
125import android.content.pm.ProviderInfo;
126import android.content.pm.ResolveInfo;
127import android.content.pm.ServiceInfo;
128import android.content.res.CompatibilityInfo;
129import android.content.res.Configuration;
130import android.graphics.Bitmap;
131import android.net.Proxy;
132import android.net.ProxyProperties;
133import android.net.Uri;
134import android.os.Binder;
135import android.os.Build;
136import android.os.Bundle;
137import android.os.Debug;
138import android.os.DropBoxManager;
139import android.os.Environment;
140import android.os.FactoryTest;
141import android.os.FileObserver;
142import android.os.FileUtils;
143import android.os.Handler;
144import android.os.IBinder;
145import android.os.IPermissionController;
146import android.os.IRemoteCallback;
147import android.os.IUserManager;
148import android.os.Looper;
149import android.os.Message;
150import android.os.Parcel;
151import android.os.ParcelFileDescriptor;
152import android.os.Process;
153import android.os.RemoteCallbackList;
154import android.os.RemoteException;
155import android.os.SELinux;
156import android.os.ServiceManager;
157import android.os.StrictMode;
158import android.os.SystemClock;
159import android.os.SystemProperties;
160import android.os.UpdateLock;
161import android.os.UserHandle;
162import android.provider.Settings;
163import android.text.format.DateUtils;
164import android.text.format.Time;
165import android.util.AtomicFile;
166import android.util.EventLog;
167import android.util.Log;
168import android.util.Pair;
169import android.util.PrintWriterPrinter;
170import android.util.Slog;
171import android.util.SparseArray;
172import android.util.TimeUtils;
173import android.util.Xml;
174import android.view.Gravity;
175import android.view.LayoutInflater;
176import android.view.View;
177import android.view.WindowManager;
178
179import java.io.BufferedInputStream;
180import java.io.BufferedOutputStream;
181import java.io.DataInputStream;
182import java.io.DataOutputStream;
183import java.io.File;
184import java.io.FileDescriptor;
185import java.io.FileInputStream;
186import java.io.FileNotFoundException;
187import java.io.FileOutputStream;
188import java.io.IOException;
189import java.io.InputStreamReader;
190import java.io.PrintWriter;
191import java.io.StringWriter;
192import java.lang.ref.WeakReference;
193import java.util.ArrayList;
194import java.util.Arrays;
195import java.util.Collections;
196import java.util.Comparator;
197import java.util.HashMap;
198import java.util.HashSet;
199import java.util.Iterator;
200import java.util.List;
201import java.util.Locale;
202import java.util.Map;
203import java.util.Set;
204import java.util.concurrent.atomic.AtomicBoolean;
205import java.util.concurrent.atomic.AtomicLong;
206
207public final class ActivityManagerService extends ActivityManagerNative
208        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
209    private static final String USER_DATA_DIR = "/data/user/";
210    static final String TAG = "ActivityManager";
211    static final String TAG_MU = "ActivityManagerServiceMU";
212    static final boolean DEBUG = false;
213    static final boolean localLOGV = DEBUG;
214    static final boolean DEBUG_BACKUP = localLOGV || false;
215    static final boolean DEBUG_BROADCAST = localLOGV || false;
216    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
217    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
218    static final boolean DEBUG_CLEANUP = localLOGV || false;
219    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
220    static final boolean DEBUG_FOCUS = false;
221    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
222    static final boolean DEBUG_MU = localLOGV || false;
223    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
224    static final boolean DEBUG_LRU = localLOGV || false;
225    static final boolean DEBUG_PAUSE = localLOGV || false;
226    static final boolean DEBUG_POWER = localLOGV || false;
227    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
228    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
229    static final boolean DEBUG_PROCESSES = localLOGV || false;
230    static final boolean DEBUG_PROVIDER = localLOGV || false;
231    static final boolean DEBUG_RESULTS = localLOGV || false;
232    static final boolean DEBUG_SERVICE = localLOGV || false;
233    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
234    static final boolean DEBUG_STACK = localLOGV || false;
235    static final boolean DEBUG_SWITCH = localLOGV || false;
236    static final boolean DEBUG_TASKS = localLOGV || false;
237    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
238    static final boolean DEBUG_TRANSITION = localLOGV || false;
239    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
240    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
241    static final boolean DEBUG_VISBILITY = localLOGV || false;
242    static final boolean DEBUG_PSS = localLOGV || false;
243    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
244    static final boolean VALIDATE_TOKENS = false;
245    static final boolean SHOW_ACTIVITY_START_TIME = true;
246
247    // Control over CPU and battery monitoring.
248    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
249    static final boolean MONITOR_CPU_USAGE = true;
250    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
251    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
252    static final boolean MONITOR_THREAD_CPU_USAGE = false;
253
254    // The flags that are set for all calls we make to the package manager.
255    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
256
257    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
258
259    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
260
261    // Maximum number of recent tasks that we can remember.
262    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20;
263
264    // Amount of time after a call to stopAppSwitches() during which we will
265    // prevent further untrusted switches from happening.
266    static final long APP_SWITCH_DELAY_TIME = 5*1000;
267
268    // How long we wait for a launched process to attach to the activity manager
269    // before we decide it's never going to come up for real.
270    static final int PROC_START_TIMEOUT = 10*1000;
271
272    // How long we wait for a launched process to attach to the activity manager
273    // before we decide it's never going to come up for real, when the process was
274    // started with a wrapper for instrumentation (such as Valgrind) because it
275    // could take much longer than usual.
276    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
277
278    // How long to wait after going idle before forcing apps to GC.
279    static final int GC_TIMEOUT = 5*1000;
280
281    // The minimum amount of time between successive GC requests for a process.
282    static final int GC_MIN_INTERVAL = 60*1000;
283
284    // The minimum amount of time between successive PSS requests for a process.
285    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
286
287    // The minimum amount of time between successive PSS requests for a process
288    // when the request is due to the memory state being lowered.
289    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
290
291    // The rate at which we check for apps using excessive power -- 15 mins.
292    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
293
294    // The minimum sample duration we will allow before deciding we have
295    // enough data on wake locks to start killing things.
296    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
297
298    // The minimum sample duration we will allow before deciding we have
299    // enough data on CPU usage to start killing things.
300    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
301
302    // How long we allow a receiver to run before giving up on it.
303    static final int BROADCAST_FG_TIMEOUT = 10*1000;
304    static final int BROADCAST_BG_TIMEOUT = 60*1000;
305
306    // How long we wait until we timeout on key dispatching.
307    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
308
309    // How long we wait until we timeout on key dispatching during instrumentation.
310    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
311
312    // Amount of time we wait for observers to handle a user switch before
313    // giving up on them and unfreezing the screen.
314    static final int USER_SWITCH_TIMEOUT = 2*1000;
315
316    // Maximum number of users we allow to be running at a time.
317    static final int MAX_RUNNING_USERS = 3;
318
319    // How long to wait in getAssistContextExtras for the activity and foreground services
320    // to respond with the result.
321    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
322
323    // Maximum number of persisted Uri grants a package is allowed
324    static final int MAX_PERSISTED_URI_GRANTS = 128;
325
326    static final int MY_PID = Process.myPid();
327
328    static final String[] EMPTY_STRING_ARRAY = new String[0];
329
330    // How many bytes to write into the dropbox log before truncating
331    static final int DROPBOX_MAX_SIZE = 256 * 1024;
332
333    /** Run all ActivityStacks through this */
334    ActivityStackSupervisor mStackSupervisor;
335
336    public IntentFirewall mIntentFirewall;
337
338    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
339    // default actuion automatically.  Important for devices without direct input
340    // devices.
341    private boolean mShowDialogs = true;
342
343    /**
344     * Description of a request to start a new activity, which has been held
345     * due to app switches being disabled.
346     */
347    static class PendingActivityLaunch {
348        final ActivityRecord r;
349        final ActivityRecord sourceRecord;
350        final int startFlags;
351        final ActivityStack stack;
352
353        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
354                int _startFlags, ActivityStack _stack) {
355            r = _r;
356            sourceRecord = _sourceRecord;
357            startFlags = _startFlags;
358            stack = _stack;
359        }
360    }
361
362    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
363            = new ArrayList<PendingActivityLaunch>();
364
365    BroadcastQueue mFgBroadcastQueue;
366    BroadcastQueue mBgBroadcastQueue;
367    // Convenient for easy iteration over the queues. Foreground is first
368    // so that dispatch of foreground broadcasts gets precedence.
369    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
370
371    BroadcastQueue broadcastQueueForIntent(Intent intent) {
372        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
373        if (DEBUG_BACKGROUND_BROADCAST) {
374            Slog.i(TAG, "Broadcast intent " + intent + " on "
375                    + (isFg ? "foreground" : "background")
376                    + " queue");
377        }
378        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
379    }
380
381    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
382        for (BroadcastQueue queue : mBroadcastQueues) {
383            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
384            if (r != null) {
385                return r;
386            }
387        }
388        return null;
389    }
390
391    /**
392     * Activity we have told the window manager to have key focus.
393     */
394    ActivityRecord mFocusedActivity = null;
395
396    /**
397     * List of intents that were used to start the most recent tasks.
398     */
399    private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
400
401    public class PendingAssistExtras extends Binder implements Runnable {
402        public final ActivityRecord activity;
403        public boolean haveResult = false;
404        public Bundle result = null;
405        public PendingAssistExtras(ActivityRecord _activity) {
406            activity = _activity;
407        }
408        @Override
409        public void run() {
410            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
411            synchronized (this) {
412                haveResult = true;
413                notifyAll();
414            }
415        }
416    }
417
418    final ArrayList<PendingAssistExtras> mPendingAssistExtras
419            = new ArrayList<PendingAssistExtras>();
420
421    /**
422     * Process management.
423     */
424    final ProcessList mProcessList = new ProcessList();
425
426    /**
427     * All of the applications we currently have running organized by name.
428     * The keys are strings of the application package name (as
429     * returned by the package manager), and the keys are ApplicationRecord
430     * objects.
431     */
432    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
433
434    /**
435     * Tracking long-term execution of processes to look for abuse and other
436     * bad app behavior.
437     */
438    final ProcessStatsService mProcessStats;
439
440    /**
441     * The currently running isolated processes.
442     */
443    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
444
445    /**
446     * Counter for assigning isolated process uids, to avoid frequently reusing the
447     * same ones.
448     */
449    int mNextIsolatedProcessUid = 0;
450
451    /**
452     * The currently running heavy-weight process, if any.
453     */
454    ProcessRecord mHeavyWeightProcess = null;
455
456    /**
457     * The last time that various processes have crashed.
458     */
459    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
460
461    /**
462     * Information about a process that is currently marked as bad.
463     */
464    static final class BadProcessInfo {
465        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
466            this.time = time;
467            this.shortMsg = shortMsg;
468            this.longMsg = longMsg;
469            this.stack = stack;
470        }
471
472        final long time;
473        final String shortMsg;
474        final String longMsg;
475        final String stack;
476    }
477
478    /**
479     * Set of applications that we consider to be bad, and will reject
480     * incoming broadcasts from (which the user has no control over).
481     * Processes are added to this set when they have crashed twice within
482     * a minimum amount of time; they are removed from it when they are
483     * later restarted (hopefully due to some user action).  The value is the
484     * time it was added to the list.
485     */
486    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
487
488    /**
489     * All of the processes we currently have running organized by pid.
490     * The keys are the pid running the application.
491     *
492     * <p>NOTE: This object is protected by its own lock, NOT the global
493     * activity manager lock!
494     */
495    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
496
497    /**
498     * All of the processes that have been forced to be foreground.  The key
499     * is the pid of the caller who requested it (we hold a death
500     * link on it).
501     */
502    abstract class ForegroundToken implements IBinder.DeathRecipient {
503        int pid;
504        IBinder token;
505    }
506    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
507
508    /**
509     * List of records for processes that someone had tried to start before the
510     * system was ready.  We don't start them at that point, but ensure they
511     * are started by the time booting is complete.
512     */
513    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
514
515    /**
516     * List of persistent applications that are in the process
517     * of being started.
518     */
519    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
520
521    /**
522     * Processes that are being forcibly torn down.
523     */
524    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
525
526    /**
527     * List of running applications, sorted by recent usage.
528     * The first entry in the list is the least recently used.
529     */
530    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
531
532    /**
533     * Where in mLruProcesses that the processes hosting activities start.
534     */
535    int mLruProcessActivityStart = 0;
536
537    /**
538     * Where in mLruProcesses that the processes hosting services start.
539     * This is after (lower index) than mLruProcessesActivityStart.
540     */
541    int mLruProcessServiceStart = 0;
542
543    /**
544     * List of processes that should gc as soon as things are idle.
545     */
546    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
547
548    /**
549     * Processes we want to collect PSS data from.
550     */
551    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
552
553    /**
554     * Last time we requested PSS data of all processes.
555     */
556    long mLastFullPssTime = SystemClock.uptimeMillis();
557
558    /**
559     * This is the process holding what we currently consider to be
560     * the "home" activity.
561     */
562    ProcessRecord mHomeProcess;
563
564    /**
565     * This is the process holding the activity the user last visited that
566     * is in a different process from the one they are currently in.
567     */
568    ProcessRecord mPreviousProcess;
569
570    /**
571     * The time at which the previous process was last visible.
572     */
573    long mPreviousProcessVisibleTime;
574
575    /**
576     * Which uses have been started, so are allowed to run code.
577     */
578    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
579
580    /**
581     * LRU list of history of current users.  Most recently current is at the end.
582     */
583    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
584
585    /**
586     * Constant array of the users that are currently started.
587     */
588    int[] mStartedUserArray = new int[] { 0 };
589
590    /**
591     * Registered observers of the user switching mechanics.
592     */
593    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
594            = new RemoteCallbackList<IUserSwitchObserver>();
595
596    /**
597     * Currently active user switch.
598     */
599    Object mCurUserSwitchCallback;
600
601    /**
602     * Packages that the user has asked to have run in screen size
603     * compatibility mode instead of filling the screen.
604     */
605    final CompatModePackages mCompatModePackages;
606
607    /**
608     * Set of IntentSenderRecord objects that are currently active.
609     */
610    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
611            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
612
613    /**
614     * Fingerprints (hashCode()) of stack traces that we've
615     * already logged DropBox entries for.  Guarded by itself.  If
616     * something (rogue user app) forces this over
617     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
618     */
619    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
620    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
621
622    /**
623     * Strict Mode background batched logging state.
624     *
625     * The string buffer is guarded by itself, and its lock is also
626     * used to determine if another batched write is already
627     * in-flight.
628     */
629    private final StringBuilder mStrictModeBuffer = new StringBuilder();
630
631    /**
632     * Keeps track of all IIntentReceivers that have been registered for
633     * broadcasts.  Hash keys are the receiver IBinder, hash value is
634     * a ReceiverList.
635     */
636    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
637            new HashMap<IBinder, ReceiverList>();
638
639    /**
640     * Resolver for broadcast intents to registered receivers.
641     * Holds BroadcastFilter (subclass of IntentFilter).
642     */
643    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
644            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
645        @Override
646        protected boolean allowFilterResult(
647                BroadcastFilter filter, List<BroadcastFilter> dest) {
648            IBinder target = filter.receiverList.receiver.asBinder();
649            for (int i=dest.size()-1; i>=0; i--) {
650                if (dest.get(i).receiverList.receiver.asBinder() == target) {
651                    return false;
652                }
653            }
654            return true;
655        }
656
657        @Override
658        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
659            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
660                    || userId == filter.owningUserId) {
661                return super.newResult(filter, match, userId);
662            }
663            return null;
664        }
665
666        @Override
667        protected BroadcastFilter[] newArray(int size) {
668            return new BroadcastFilter[size];
669        }
670
671        @Override
672        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
673            return packageName.equals(filter.packageName);
674        }
675    };
676
677    /**
678     * State of all active sticky broadcasts per user.  Keys are the action of the
679     * sticky Intent, values are an ArrayList of all broadcasted intents with
680     * that action (which should usually be one).  The SparseArray is keyed
681     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
682     * for stickies that are sent to all users.
683     */
684    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
685            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
686
687    final ActiveServices mServices;
688
689    /**
690     * Backup/restore process management
691     */
692    String mBackupAppName = null;
693    BackupRecord mBackupTarget = null;
694
695    /**
696     * List of PendingThumbnailsRecord objects of clients who are still
697     * waiting to receive all of the thumbnails for a task.
698     */
699    final ArrayList<PendingThumbnailsRecord> mPendingThumbnails =
700            new ArrayList<PendingThumbnailsRecord>();
701
702    final ProviderMap mProviderMap;
703
704    /**
705     * List of content providers who have clients waiting for them.  The
706     * application is currently being launched and the provider will be
707     * removed from this list once it is published.
708     */
709    final ArrayList<ContentProviderRecord> mLaunchingProviders
710            = new ArrayList<ContentProviderRecord>();
711
712    /**
713     * File storing persisted {@link #mGrantedUriPermissions}.
714     */
715    private final AtomicFile mGrantFile;
716
717    /** XML constants used in {@link #mGrantFile} */
718    private static final String TAG_URI_GRANTS = "uri-grants";
719    private static final String TAG_URI_GRANT = "uri-grant";
720    private static final String ATTR_USER_HANDLE = "userHandle";
721    private static final String ATTR_SOURCE_PKG = "sourcePkg";
722    private static final String ATTR_TARGET_PKG = "targetPkg";
723    private static final String ATTR_URI = "uri";
724    private static final String ATTR_MODE_FLAGS = "modeFlags";
725    private static final String ATTR_CREATED_TIME = "createdTime";
726
727    /**
728     * Global set of specific {@link Uri} permissions that have been granted.
729     * This optimized lookup structure maps from {@link UriPermission#targetUid}
730     * to {@link UriPermission#uri} to {@link UriPermission}.
731     */
732    @GuardedBy("this")
733    private final SparseArray<ArrayMap<Uri, UriPermission>>
734            mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>();
735
736    CoreSettingsObserver mCoreSettingsObserver;
737
738    /**
739     * Thread-local storage used to carry caller permissions over through
740     * indirect content-provider access.
741     */
742    private class Identity {
743        public int pid;
744        public int uid;
745
746        Identity(int _pid, int _uid) {
747            pid = _pid;
748            uid = _uid;
749        }
750    }
751
752    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
753
754    /**
755     * All information we have collected about the runtime performance of
756     * any user id that can impact battery performance.
757     */
758    final BatteryStatsService mBatteryStatsService;
759
760    /**
761     * Information about component usage
762     */
763    final UsageStatsService mUsageStatsService;
764
765    /**
766     * Information about and control over application operations
767     */
768    final AppOpsService mAppOpsService;
769
770    /**
771     * Current configuration information.  HistoryRecord objects are given
772     * a reference to this object to indicate which configuration they are
773     * currently running in, so this object must be kept immutable.
774     */
775    Configuration mConfiguration = new Configuration();
776
777    /**
778     * Current sequencing integer of the configuration, for skipping old
779     * configurations.
780     */
781    int mConfigurationSeq = 0;
782
783    /**
784     * Hardware-reported OpenGLES version.
785     */
786    final int GL_ES_VERSION;
787
788    /**
789     * List of initialization arguments to pass to all processes when binding applications to them.
790     * For example, references to the commonly used services.
791     */
792    HashMap<String, IBinder> mAppBindArgs;
793
794    /**
795     * Temporary to avoid allocations.  Protected by main lock.
796     */
797    final StringBuilder mStringBuilder = new StringBuilder(256);
798
799    /**
800     * Used to control how we initialize the service.
801     */
802    boolean mStartRunning = false;
803    ComponentName mTopComponent;
804    String mTopAction;
805    String mTopData;
806    boolean mProcessesReady = false;
807    boolean mSystemReady = false;
808    boolean mBooting = false;
809    boolean mWaitingUpdate = false;
810    boolean mDidUpdate = false;
811    boolean mOnBattery = false;
812    boolean mLaunchWarningShown = false;
813
814    Context mContext;
815
816    int mFactoryTest;
817
818    boolean mCheckedForSetup;
819
820    /**
821     * The time at which we will allow normal application switches again,
822     * after a call to {@link #stopAppSwitches()}.
823     */
824    long mAppSwitchesAllowedTime;
825
826    /**
827     * This is set to true after the first switch after mAppSwitchesAllowedTime
828     * is set; any switches after that will clear the time.
829     */
830    boolean mDidAppSwitch;
831
832    /**
833     * Last time (in realtime) at which we checked for power usage.
834     */
835    long mLastPowerCheckRealtime;
836
837    /**
838     * Last time (in uptime) at which we checked for power usage.
839     */
840    long mLastPowerCheckUptime;
841
842    /**
843     * Set while we are wanting to sleep, to prevent any
844     * activities from being started/resumed.
845     */
846    boolean mSleeping = false;
847
848    /**
849     * State of external calls telling us if the device is asleep.
850     */
851    boolean mWentToSleep = false;
852
853    /**
854     * State of external call telling us if the lock screen is shown.
855     */
856    boolean mLockScreenShown = false;
857
858    /**
859     * Set if we are shutting down the system, similar to sleeping.
860     */
861    boolean mShuttingDown = false;
862
863    /**
864     * Current sequence id for oom_adj computation traversal.
865     */
866    int mAdjSeq = 0;
867
868    /**
869     * Current sequence id for process LRU updating.
870     */
871    int mLruSeq = 0;
872
873    /**
874     * Keep track of the non-cached/empty process we last found, to help
875     * determine how to distribute cached/empty processes next time.
876     */
877    int mNumNonCachedProcs = 0;
878
879    /**
880     * Keep track of the number of cached hidden procs, to balance oom adj
881     * distribution between those and empty procs.
882     */
883    int mNumCachedHiddenProcs = 0;
884
885    /**
886     * Keep track of the number of service processes we last found, to
887     * determine on the next iteration which should be B services.
888     */
889    int mNumServiceProcs = 0;
890    int mNewNumAServiceProcs = 0;
891    int mNewNumServiceProcs = 0;
892
893    /**
894     * Allow the current computed overall memory level of the system to go down?
895     * This is set to false when we are killing processes for reasons other than
896     * memory management, so that the now smaller process list will not be taken as
897     * an indication that memory is tighter.
898     */
899    boolean mAllowLowerMemLevel = false;
900
901    /**
902     * The last computed memory level, for holding when we are in a state that
903     * processes are going away for other reasons.
904     */
905    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
906
907    /**
908     * The last total number of process we have, to determine if changes actually look
909     * like a shrinking number of process due to lower RAM.
910     */
911    int mLastNumProcesses;
912
913    /**
914     * The uptime of the last time we performed idle maintenance.
915     */
916    long mLastIdleTime = SystemClock.uptimeMillis();
917
918    /**
919     * Total time spent with RAM that has been added in the past since the last idle time.
920     */
921    long mLowRamTimeSinceLastIdle = 0;
922
923    /**
924     * If RAM is currently low, when that horrible situation started.
925     */
926    long mLowRamStartTime = 0;
927
928    /**
929     * For reporting to battery stats the current top application.
930     */
931    private String mCurResumedPackage = null;
932    private int mCurResumedUid = -1;
933
934    /**
935     * For reporting to battery stats the apps currently running foreground
936     * service.  The ProcessMap is package/uid tuples; each of these contain
937     * an array of the currently foreground processes.
938     */
939    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
940            = new ProcessMap<ArrayList<ProcessRecord>>();
941
942    /**
943     * This is set if we had to do a delayed dexopt of an app before launching
944     * it, to increasing the ANR timeouts in that case.
945     */
946    boolean mDidDexOpt;
947
948    String mDebugApp = null;
949    boolean mWaitForDebugger = false;
950    boolean mDebugTransient = false;
951    String mOrigDebugApp = null;
952    boolean mOrigWaitForDebugger = false;
953    boolean mAlwaysFinishActivities = false;
954    IActivityController mController = null;
955    String mProfileApp = null;
956    ProcessRecord mProfileProc = null;
957    String mProfileFile;
958    ParcelFileDescriptor mProfileFd;
959    int mProfileType = 0;
960    boolean mAutoStopProfiler = false;
961    String mOpenGlTraceApp = null;
962
963    static class ProcessChangeItem {
964        static final int CHANGE_ACTIVITIES = 1<<0;
965        static final int CHANGE_IMPORTANCE= 1<<1;
966        int changes;
967        int uid;
968        int pid;
969        int importance;
970        boolean foregroundActivities;
971    }
972
973    final RemoteCallbackList<IProcessObserver> mProcessObservers
974            = new RemoteCallbackList<IProcessObserver>();
975    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
976
977    final ArrayList<ProcessChangeItem> mPendingProcessChanges
978            = new ArrayList<ProcessChangeItem>();
979    final ArrayList<ProcessChangeItem> mAvailProcessChanges
980            = new ArrayList<ProcessChangeItem>();
981
982    /**
983     * Runtime CPU use collection thread.  This object's lock is used to
984     * protect all related state.
985     */
986    final Thread mProcessCpuThread;
987
988    /**
989     * Used to collect process stats when showing not responding dialog.
990     * Protected by mProcessCpuThread.
991     */
992    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
993            MONITOR_THREAD_CPU_USAGE);
994    final AtomicLong mLastCpuTime = new AtomicLong(0);
995    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
996
997    long mLastWriteTime = 0;
998
999    /**
1000     * Used to retain an update lock when the foreground activity is in
1001     * immersive mode.
1002     */
1003    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1004
1005    /**
1006     * Set to true after the system has finished booting.
1007     */
1008    boolean mBooted = false;
1009
1010    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1011    int mProcessLimitOverride = -1;
1012
1013    WindowManagerService mWindowManager;
1014
1015    final ActivityThread mSystemThread;
1016
1017    int mCurrentUserId = 0;
1018    int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack
1019    private UserManagerService mUserManager;
1020
1021    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1022        final ProcessRecord mApp;
1023        final int mPid;
1024        final IApplicationThread mAppThread;
1025
1026        AppDeathRecipient(ProcessRecord app, int pid,
1027                IApplicationThread thread) {
1028            if (localLOGV) Slog.v(
1029                TAG, "New death recipient " + this
1030                + " for thread " + thread.asBinder());
1031            mApp = app;
1032            mPid = pid;
1033            mAppThread = thread;
1034        }
1035
1036        @Override
1037        public void binderDied() {
1038            if (localLOGV) Slog.v(
1039                TAG, "Death received in " + this
1040                + " for thread " + mAppThread.asBinder());
1041            synchronized(ActivityManagerService.this) {
1042                appDiedLocked(mApp, mPid, mAppThread);
1043            }
1044        }
1045    }
1046
1047    static final int SHOW_ERROR_MSG = 1;
1048    static final int SHOW_NOT_RESPONDING_MSG = 2;
1049    static final int SHOW_FACTORY_ERROR_MSG = 3;
1050    static final int UPDATE_CONFIGURATION_MSG = 4;
1051    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1052    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1053    static final int SERVICE_TIMEOUT_MSG = 12;
1054    static final int UPDATE_TIME_ZONE = 13;
1055    static final int SHOW_UID_ERROR_MSG = 14;
1056    static final int IM_FEELING_LUCKY_MSG = 15;
1057    static final int PROC_START_TIMEOUT_MSG = 20;
1058    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1059    static final int KILL_APPLICATION_MSG = 22;
1060    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1061    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1062    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1063    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1064    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1065    static final int CLEAR_DNS_CACHE_MSG = 28;
1066    static final int UPDATE_HTTP_PROXY_MSG = 29;
1067    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1068    static final int DISPATCH_PROCESSES_CHANGED = 31;
1069    static final int DISPATCH_PROCESS_DIED = 32;
1070    static final int REPORT_MEM_USAGE_MSG = 33;
1071    static final int REPORT_USER_SWITCH_MSG = 34;
1072    static final int CONTINUE_USER_SWITCH_MSG = 35;
1073    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1074    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1075    static final int PERSIST_URI_GRANTS_MSG = 38;
1076    static final int REQUEST_ALL_PSS_MSG = 39;
1077    static final int START_RELATED_USERS_MSG = 40;
1078    static final int UPDATE_TIME = 41;
1079
1080    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1081    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1082    static final int FIRST_COMPAT_MODE_MSG = 300;
1083    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1084
1085    AlertDialog mUidAlert;
1086    CompatModeDialog mCompatModeDialog;
1087    long mLastMemUsageReportTime = 0;
1088
1089    /**
1090     * Flag whether the current user is a "monkey", i.e. whether
1091     * the UI is driven by a UI automation tool.
1092     */
1093    private boolean mUserIsMonkey;
1094
1095    final ServiceThread mHandlerThread;
1096    final MainHandler mHandler;
1097
1098    final class MainHandler extends Handler {
1099        public MainHandler(Looper looper) {
1100            super(looper, null, true);
1101        }
1102
1103        @Override
1104        public void handleMessage(Message msg) {
1105            switch (msg.what) {
1106            case SHOW_ERROR_MSG: {
1107                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1108                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1109                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1110                synchronized (ActivityManagerService.this) {
1111                    ProcessRecord proc = (ProcessRecord)data.get("app");
1112                    AppErrorResult res = (AppErrorResult) data.get("result");
1113                    if (proc != null && proc.crashDialog != null) {
1114                        Slog.e(TAG, "App already has crash dialog: " + proc);
1115                        if (res != null) {
1116                            res.set(0);
1117                        }
1118                        return;
1119                    }
1120                    if (!showBackground && UserHandle.getAppId(proc.uid)
1121                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1122                            && proc.pid != MY_PID) {
1123                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1124                        if (res != null) {
1125                            res.set(0);
1126                        }
1127                        return;
1128                    }
1129                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1130                        Dialog d = new AppErrorDialog(mContext,
1131                                ActivityManagerService.this, res, proc);
1132                        d.show();
1133                        proc.crashDialog = d;
1134                    } else {
1135                        // The device is asleep, so just pretend that the user
1136                        // saw a crash dialog and hit "force quit".
1137                        if (res != null) {
1138                            res.set(0);
1139                        }
1140                    }
1141                }
1142
1143                ensureBootCompleted();
1144            } break;
1145            case SHOW_NOT_RESPONDING_MSG: {
1146                synchronized (ActivityManagerService.this) {
1147                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1148                    ProcessRecord proc = (ProcessRecord)data.get("app");
1149                    if (proc != null && proc.anrDialog != null) {
1150                        Slog.e(TAG, "App already has anr dialog: " + proc);
1151                        return;
1152                    }
1153
1154                    Intent intent = new Intent("android.intent.action.ANR");
1155                    if (!mProcessesReady) {
1156                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1157                                | Intent.FLAG_RECEIVER_FOREGROUND);
1158                    }
1159                    broadcastIntentLocked(null, null, intent,
1160                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1161                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1162
1163                    if (mShowDialogs) {
1164                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1165                                mContext, proc, (ActivityRecord)data.get("activity"),
1166                                msg.arg1 != 0);
1167                        d.show();
1168                        proc.anrDialog = d;
1169                    } else {
1170                        // Just kill the app if there is no dialog to be shown.
1171                        killAppAtUsersRequest(proc, null);
1172                    }
1173                }
1174
1175                ensureBootCompleted();
1176            } break;
1177            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1178                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1179                synchronized (ActivityManagerService.this) {
1180                    ProcessRecord proc = (ProcessRecord) data.get("app");
1181                    if (proc == null) {
1182                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1183                        break;
1184                    }
1185                    if (proc.crashDialog != null) {
1186                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1187                        return;
1188                    }
1189                    AppErrorResult res = (AppErrorResult) data.get("result");
1190                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1191                        Dialog d = new StrictModeViolationDialog(mContext,
1192                                ActivityManagerService.this, res, proc);
1193                        d.show();
1194                        proc.crashDialog = d;
1195                    } else {
1196                        // The device is asleep, so just pretend that the user
1197                        // saw a crash dialog and hit "force quit".
1198                        res.set(0);
1199                    }
1200                }
1201                ensureBootCompleted();
1202            } break;
1203            case SHOW_FACTORY_ERROR_MSG: {
1204                Dialog d = new FactoryErrorDialog(
1205                    mContext, msg.getData().getCharSequence("msg"));
1206                d.show();
1207                ensureBootCompleted();
1208            } break;
1209            case UPDATE_CONFIGURATION_MSG: {
1210                final ContentResolver resolver = mContext.getContentResolver();
1211                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1212            } break;
1213            case GC_BACKGROUND_PROCESSES_MSG: {
1214                synchronized (ActivityManagerService.this) {
1215                    performAppGcsIfAppropriateLocked();
1216                }
1217            } break;
1218            case WAIT_FOR_DEBUGGER_MSG: {
1219                synchronized (ActivityManagerService.this) {
1220                    ProcessRecord app = (ProcessRecord)msg.obj;
1221                    if (msg.arg1 != 0) {
1222                        if (!app.waitedForDebugger) {
1223                            Dialog d = new AppWaitingForDebuggerDialog(
1224                                    ActivityManagerService.this,
1225                                    mContext, app);
1226                            app.waitDialog = d;
1227                            app.waitedForDebugger = true;
1228                            d.show();
1229                        }
1230                    } else {
1231                        if (app.waitDialog != null) {
1232                            app.waitDialog.dismiss();
1233                            app.waitDialog = null;
1234                        }
1235                    }
1236                }
1237            } break;
1238            case SERVICE_TIMEOUT_MSG: {
1239                if (mDidDexOpt) {
1240                    mDidDexOpt = false;
1241                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1242                    nmsg.obj = msg.obj;
1243                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1244                    return;
1245                }
1246                mServices.serviceTimeout((ProcessRecord)msg.obj);
1247            } break;
1248            case UPDATE_TIME_ZONE: {
1249                synchronized (ActivityManagerService.this) {
1250                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1251                        ProcessRecord r = mLruProcesses.get(i);
1252                        if (r.thread != null) {
1253                            try {
1254                                r.thread.updateTimeZone();
1255                            } catch (RemoteException ex) {
1256                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1257                            }
1258                        }
1259                    }
1260                }
1261            } break;
1262            case CLEAR_DNS_CACHE_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1265                        ProcessRecord r = mLruProcesses.get(i);
1266                        if (r.thread != null) {
1267                            try {
1268                                r.thread.clearDnsCache();
1269                            } catch (RemoteException ex) {
1270                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1271                            }
1272                        }
1273                    }
1274                }
1275            } break;
1276            case UPDATE_HTTP_PROXY_MSG: {
1277                ProxyProperties proxy = (ProxyProperties)msg.obj;
1278                String host = "";
1279                String port = "";
1280                String exclList = "";
1281                String pacFileUrl = null;
1282                if (proxy != null) {
1283                    host = proxy.getHost();
1284                    port = Integer.toString(proxy.getPort());
1285                    exclList = proxy.getExclusionList();
1286                    pacFileUrl = proxy.getPacFileUrl();
1287                }
1288                synchronized (ActivityManagerService.this) {
1289                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1290                        ProcessRecord r = mLruProcesses.get(i);
1291                        if (r.thread != null) {
1292                            try {
1293                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1294                            } catch (RemoteException ex) {
1295                                Slog.w(TAG, "Failed to update http proxy for: " +
1296                                        r.info.processName);
1297                            }
1298                        }
1299                    }
1300                }
1301            } break;
1302            case SHOW_UID_ERROR_MSG: {
1303                String title = "System UIDs Inconsistent";
1304                String text = "UIDs on the system are inconsistent, you need to wipe your"
1305                        + " data partition or your device will be unstable.";
1306                Log.e(TAG, title + ": " + text);
1307                if (mShowDialogs) {
1308                    // XXX This is a temporary dialog, no need to localize.
1309                    AlertDialog d = new BaseErrorDialog(mContext);
1310                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1311                    d.setCancelable(false);
1312                    d.setTitle(title);
1313                    d.setMessage(text);
1314                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1315                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1316                    mUidAlert = d;
1317                    d.show();
1318                }
1319            } break;
1320            case IM_FEELING_LUCKY_MSG: {
1321                if (mUidAlert != null) {
1322                    mUidAlert.dismiss();
1323                    mUidAlert = null;
1324                }
1325            } break;
1326            case PROC_START_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1332                    return;
1333                }
1334                ProcessRecord app = (ProcessRecord)msg.obj;
1335                synchronized (ActivityManagerService.this) {
1336                    processStartTimedOutLocked(app);
1337                }
1338            } break;
1339            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1340                synchronized (ActivityManagerService.this) {
1341                    doPendingActivityLaunchesLocked(true);
1342                }
1343            } break;
1344            case KILL_APPLICATION_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    int appid = msg.arg1;
1347                    boolean restart = (msg.arg2 == 1);
1348                    Bundle bundle = (Bundle)msg.obj;
1349                    String pkg = bundle.getString("pkg");
1350                    String reason = bundle.getString("reason");
1351                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1352                            false, UserHandle.USER_ALL, reason);
1353                }
1354            } break;
1355            case FINALIZE_PENDING_INTENT_MSG: {
1356                ((PendingIntentRecord)msg.obj).completeFinalize();
1357            } break;
1358            case POST_HEAVY_NOTIFICATION_MSG: {
1359                INotificationManager inm = NotificationManager.getService();
1360                if (inm == null) {
1361                    return;
1362                }
1363
1364                ActivityRecord root = (ActivityRecord)msg.obj;
1365                ProcessRecord process = root.app;
1366                if (process == null) {
1367                    return;
1368                }
1369
1370                try {
1371                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1372                    String text = mContext.getString(R.string.heavy_weight_notification,
1373                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1374                    Notification notification = new Notification();
1375                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1376                    notification.when = 0;
1377                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1378                    notification.tickerText = text;
1379                    notification.defaults = 0; // please be quiet
1380                    notification.sound = null;
1381                    notification.vibrate = null;
1382                    notification.setLatestEventInfo(context, text,
1383                            mContext.getText(R.string.heavy_weight_notification_detail),
1384                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1385                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1386                                    new UserHandle(root.userId)));
1387
1388                    try {
1389                        int[] outId = new int[1];
1390                        inm.enqueueNotificationWithTag("android", "android", null,
1391                                R.string.heavy_weight_notification,
1392                                notification, outId, root.userId);
1393                    } catch (RuntimeException e) {
1394                        Slog.w(ActivityManagerService.TAG,
1395                                "Error showing notification for heavy-weight app", e);
1396                    } catch (RemoteException e) {
1397                    }
1398                } catch (NameNotFoundException e) {
1399                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1400                }
1401            } break;
1402            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1403                INotificationManager inm = NotificationManager.getService();
1404                if (inm == null) {
1405                    return;
1406                }
1407                try {
1408                    inm.cancelNotificationWithTag("android", null,
1409                            R.string.heavy_weight_notification,  msg.arg1);
1410                } catch (RuntimeException e) {
1411                    Slog.w(ActivityManagerService.TAG,
1412                            "Error canceling notification for service", e);
1413                } catch (RemoteException e) {
1414                }
1415            } break;
1416            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1417                synchronized (ActivityManagerService.this) {
1418                    checkExcessivePowerUsageLocked(true);
1419                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1420                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1421                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1422                }
1423            } break;
1424            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1425                synchronized (ActivityManagerService.this) {
1426                    ActivityRecord ar = (ActivityRecord)msg.obj;
1427                    if (mCompatModeDialog != null) {
1428                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1429                                ar.info.applicationInfo.packageName)) {
1430                            return;
1431                        }
1432                        mCompatModeDialog.dismiss();
1433                        mCompatModeDialog = null;
1434                    }
1435                    if (ar != null && false) {
1436                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1437                                ar.packageName)) {
1438                            int mode = mCompatModePackages.computeCompatModeLocked(
1439                                    ar.info.applicationInfo);
1440                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1441                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1442                                mCompatModeDialog = new CompatModeDialog(
1443                                        ActivityManagerService.this, mContext,
1444                                        ar.info.applicationInfo);
1445                                mCompatModeDialog.show();
1446                            }
1447                        }
1448                    }
1449                }
1450                break;
1451            }
1452            case DISPATCH_PROCESSES_CHANGED: {
1453                dispatchProcessesChanged();
1454                break;
1455            }
1456            case DISPATCH_PROCESS_DIED: {
1457                final int pid = msg.arg1;
1458                final int uid = msg.arg2;
1459                dispatchProcessDied(pid, uid);
1460                break;
1461            }
1462            case REPORT_MEM_USAGE_MSG: {
1463                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1464                Thread thread = new Thread() {
1465                    @Override public void run() {
1466                        final SparseArray<ProcessMemInfo> infoMap
1467                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1468                        for (int i=0, N=memInfos.size(); i<N; i++) {
1469                            ProcessMemInfo mi = memInfos.get(i);
1470                            infoMap.put(mi.pid, mi);
1471                        }
1472                        updateCpuStatsNow();
1473                        synchronized (mProcessCpuThread) {
1474                            final int N = mProcessCpuTracker.countStats();
1475                            for (int i=0; i<N; i++) {
1476                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1477                                if (st.vsize > 0) {
1478                                    long pss = Debug.getPss(st.pid, null);
1479                                    if (pss > 0) {
1480                                        if (infoMap.indexOfKey(st.pid) < 0) {
1481                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1482                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1483                                            mi.pss = pss;
1484                                            memInfos.add(mi);
1485                                        }
1486                                    }
1487                                }
1488                            }
1489                        }
1490
1491                        long totalPss = 0;
1492                        for (int i=0, N=memInfos.size(); i<N; i++) {
1493                            ProcessMemInfo mi = memInfos.get(i);
1494                            if (mi.pss == 0) {
1495                                mi.pss = Debug.getPss(mi.pid, null);
1496                            }
1497                            totalPss += mi.pss;
1498                        }
1499                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1500                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1501                                if (lhs.oomAdj != rhs.oomAdj) {
1502                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1503                                }
1504                                if (lhs.pss != rhs.pss) {
1505                                    return lhs.pss < rhs.pss ? 1 : -1;
1506                                }
1507                                return 0;
1508                            }
1509                        });
1510
1511                        StringBuilder tag = new StringBuilder(128);
1512                        StringBuilder stack = new StringBuilder(128);
1513                        tag.append("Low on memory -- ");
1514                        appendMemBucket(tag, totalPss, "total", false);
1515                        appendMemBucket(stack, totalPss, "total", true);
1516
1517                        StringBuilder logBuilder = new StringBuilder(1024);
1518                        logBuilder.append("Low on memory:\n");
1519
1520                        boolean firstLine = true;
1521                        int lastOomAdj = Integer.MIN_VALUE;
1522                        for (int i=0, N=memInfos.size(); i<N; i++) {
1523                            ProcessMemInfo mi = memInfos.get(i);
1524
1525                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1526                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1527                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1528                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1529                                if (lastOomAdj != mi.oomAdj) {
1530                                    lastOomAdj = mi.oomAdj;
1531                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1532                                        tag.append(" / ");
1533                                    }
1534                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1535                                        if (firstLine) {
1536                                            stack.append(":");
1537                                            firstLine = false;
1538                                        }
1539                                        stack.append("\n\t at ");
1540                                    } else {
1541                                        stack.append("$");
1542                                    }
1543                                } else {
1544                                    tag.append(" ");
1545                                    stack.append("$");
1546                                }
1547                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1548                                    appendMemBucket(tag, mi.pss, mi.name, false);
1549                                }
1550                                appendMemBucket(stack, mi.pss, mi.name, true);
1551                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1552                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1553                                    stack.append("(");
1554                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1555                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1556                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1557                                            stack.append(":");
1558                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1559                                        }
1560                                    }
1561                                    stack.append(")");
1562                                }
1563                            }
1564
1565                            logBuilder.append("  ");
1566                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1567                            logBuilder.append(' ');
1568                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1569                            logBuilder.append(' ');
1570                            ProcessList.appendRamKb(logBuilder, mi.pss);
1571                            logBuilder.append(" kB: ");
1572                            logBuilder.append(mi.name);
1573                            logBuilder.append(" (");
1574                            logBuilder.append(mi.pid);
1575                            logBuilder.append(") ");
1576                            logBuilder.append(mi.adjType);
1577                            logBuilder.append('\n');
1578                            if (mi.adjReason != null) {
1579                                logBuilder.append("                      ");
1580                                logBuilder.append(mi.adjReason);
1581                                logBuilder.append('\n');
1582                            }
1583                        }
1584
1585                        logBuilder.append("           ");
1586                        ProcessList.appendRamKb(logBuilder, totalPss);
1587                        logBuilder.append(" kB: TOTAL\n");
1588
1589                        long[] infos = new long[Debug.MEMINFO_COUNT];
1590                        Debug.getMemInfo(infos);
1591                        logBuilder.append("  MemInfo: ");
1592                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1594                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1595                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1596                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1597                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1598                            logBuilder.append("  ZRAM: ");
1599                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1600                            logBuilder.append(" kB RAM, ");
1601                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1602                            logBuilder.append(" kB swap total, ");
1603                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1604                            logBuilder.append(" kB swap free\n");
1605                        }
1606                        Slog.i(TAG, logBuilder.toString());
1607
1608                        StringBuilder dropBuilder = new StringBuilder(1024);
1609                        /*
1610                        StringWriter oomSw = new StringWriter();
1611                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1612                        StringWriter catSw = new StringWriter();
1613                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1614                        String[] emptyArgs = new String[] { };
1615                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1616                        oomPw.flush();
1617                        String oomString = oomSw.toString();
1618                        */
1619                        dropBuilder.append(stack);
1620                        dropBuilder.append('\n');
1621                        dropBuilder.append('\n');
1622                        dropBuilder.append(logBuilder);
1623                        dropBuilder.append('\n');
1624                        /*
1625                        dropBuilder.append(oomString);
1626                        dropBuilder.append('\n');
1627                        */
1628                        StringWriter catSw = new StringWriter();
1629                        synchronized (ActivityManagerService.this) {
1630                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1631                            String[] emptyArgs = new String[] { };
1632                            catPw.println();
1633                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1634                            catPw.println();
1635                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1636                                    false, false, null);
1637                            catPw.println();
1638                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1639                            catPw.flush();
1640                        }
1641                        dropBuilder.append(catSw.toString());
1642                        addErrorToDropBox("lowmem", null, "system_server", null,
1643                                null, tag.toString(), dropBuilder.toString(), null, null);
1644                        //Slog.i(TAG, "Sent to dropbox:");
1645                        //Slog.i(TAG, dropBuilder.toString());
1646                        synchronized (ActivityManagerService.this) {
1647                            long now = SystemClock.uptimeMillis();
1648                            if (mLastMemUsageReportTime < now) {
1649                                mLastMemUsageReportTime = now;
1650                            }
1651                        }
1652                    }
1653                };
1654                thread.start();
1655                break;
1656            }
1657            case REPORT_USER_SWITCH_MSG: {
1658                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1659                break;
1660            }
1661            case CONTINUE_USER_SWITCH_MSG: {
1662                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1663                break;
1664            }
1665            case USER_SWITCH_TIMEOUT_MSG: {
1666                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1667                break;
1668            }
1669            case IMMERSIVE_MODE_LOCK_MSG: {
1670                final boolean nextState = (msg.arg1 != 0);
1671                if (mUpdateLock.isHeld() != nextState) {
1672                    if (DEBUG_IMMERSIVE) {
1673                        final ActivityRecord r = (ActivityRecord) msg.obj;
1674                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1675                    }
1676                    if (nextState) {
1677                        mUpdateLock.acquire();
1678                    } else {
1679                        mUpdateLock.release();
1680                    }
1681                }
1682                break;
1683            }
1684            case PERSIST_URI_GRANTS_MSG: {
1685                writeGrantedUriPermissions();
1686                break;
1687            }
1688            case REQUEST_ALL_PSS_MSG: {
1689                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1690                break;
1691            }
1692            case START_RELATED_USERS_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    startRelatedUsersLocked();
1695                }
1696                break;
1697            }
1698            case UPDATE_TIME: {
1699                synchronized (ActivityManagerService.this) {
1700                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1701                        ProcessRecord r = mLruProcesses.get(i);
1702                        if (r.thread != null) {
1703                            try {
1704                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1705                            } catch (RemoteException ex) {
1706                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1707                            }
1708                        }
1709                    }
1710                }
1711                break;
1712            }
1713            }
1714        }
1715    };
1716
1717    static final int COLLECT_PSS_BG_MSG = 1;
1718
1719    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1720        @Override
1721        public void handleMessage(Message msg) {
1722            switch (msg.what) {
1723            case COLLECT_PSS_BG_MSG: {
1724                int i=0, num=0;
1725                long start = SystemClock.uptimeMillis();
1726                long[] tmp = new long[1];
1727                do {
1728                    ProcessRecord proc;
1729                    int procState;
1730                    int pid;
1731                    synchronized (ActivityManagerService.this) {
1732                        if (i >= mPendingPssProcesses.size()) {
1733                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1734                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1735                            mPendingPssProcesses.clear();
1736                            return;
1737                        }
1738                        proc = mPendingPssProcesses.get(i);
1739                        procState = proc.pssProcState;
1740                        if (proc.thread != null && procState == proc.setProcState) {
1741                            pid = proc.pid;
1742                        } else {
1743                            proc = null;
1744                            pid = 0;
1745                        }
1746                        i++;
1747                    }
1748                    if (proc != null) {
1749                        long pss = Debug.getPss(pid, tmp);
1750                        synchronized (ActivityManagerService.this) {
1751                            if (proc.thread != null && proc.setProcState == procState
1752                                    && proc.pid == pid) {
1753                                num++;
1754                                proc.lastPssTime = SystemClock.uptimeMillis();
1755                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1756                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1757                                        + ": " + pss + " lastPss=" + proc.lastPss
1758                                        + " state=" + ProcessList.makeProcStateString(procState));
1759                                if (proc.initialIdlePss == 0) {
1760                                    proc.initialIdlePss = pss;
1761                                }
1762                                proc.lastPss = pss;
1763                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1764                                    proc.lastCachedPss = pss;
1765                                }
1766                            }
1767                        }
1768                    }
1769                } while (true);
1770            }
1771            }
1772        }
1773    };
1774
1775    public void setSystemProcess() {
1776        try {
1777            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1778            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1779            ServiceManager.addService("meminfo", new MemBinder(this));
1780            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1781            ServiceManager.addService("dbinfo", new DbBinder(this));
1782            if (MONITOR_CPU_USAGE) {
1783                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1784            }
1785            ServiceManager.addService("permission", new PermissionController(this));
1786
1787            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1788                    "android", STOCK_PM_FLAGS);
1789            mSystemThread.installSystemApplicationInfo(info);
1790
1791            synchronized (this) {
1792                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1793                app.persistent = true;
1794                app.pid = MY_PID;
1795                app.maxAdj = ProcessList.SYSTEM_ADJ;
1796                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1797                mProcessNames.put(app.processName, app.uid, app);
1798                synchronized (mPidsSelfLocked) {
1799                    mPidsSelfLocked.put(app.pid, app);
1800                }
1801                updateLruProcessLocked(app, false, null);
1802                updateOomAdjLocked();
1803            }
1804        } catch (PackageManager.NameNotFoundException e) {
1805            throw new RuntimeException(
1806                    "Unable to find android system package", e);
1807        }
1808    }
1809
1810    public void setWindowManager(WindowManagerService wm) {
1811        mWindowManager = wm;
1812        mStackSupervisor.setWindowManager(wm);
1813    }
1814
1815    public void startObservingNativeCrashes() {
1816        final NativeCrashListener ncl = new NativeCrashListener(this);
1817        ncl.start();
1818    }
1819
1820    public IAppOpsService getAppOpsService() {
1821        return mAppOpsService;
1822    }
1823
1824    static class MemBinder extends Binder {
1825        ActivityManagerService mActivityManagerService;
1826        MemBinder(ActivityManagerService activityManagerService) {
1827            mActivityManagerService = activityManagerService;
1828        }
1829
1830        @Override
1831        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1832            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1833                    != PackageManager.PERMISSION_GRANTED) {
1834                pw.println("Permission Denial: can't dump meminfo from from pid="
1835                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1836                        + " without permission " + android.Manifest.permission.DUMP);
1837                return;
1838            }
1839
1840            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1841        }
1842    }
1843
1844    static class GraphicsBinder extends Binder {
1845        ActivityManagerService mActivityManagerService;
1846        GraphicsBinder(ActivityManagerService activityManagerService) {
1847            mActivityManagerService = activityManagerService;
1848        }
1849
1850        @Override
1851        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1852            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1853                    != PackageManager.PERMISSION_GRANTED) {
1854                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1855                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1856                        + " without permission " + android.Manifest.permission.DUMP);
1857                return;
1858            }
1859
1860            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1861        }
1862    }
1863
1864    static class DbBinder extends Binder {
1865        ActivityManagerService mActivityManagerService;
1866        DbBinder(ActivityManagerService activityManagerService) {
1867            mActivityManagerService = activityManagerService;
1868        }
1869
1870        @Override
1871        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1872            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1873                    != PackageManager.PERMISSION_GRANTED) {
1874                pw.println("Permission Denial: can't dump dbinfo from from pid="
1875                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1876                        + " without permission " + android.Manifest.permission.DUMP);
1877                return;
1878            }
1879
1880            mActivityManagerService.dumpDbInfo(fd, pw, args);
1881        }
1882    }
1883
1884    static class CpuBinder extends Binder {
1885        ActivityManagerService mActivityManagerService;
1886        CpuBinder(ActivityManagerService activityManagerService) {
1887            mActivityManagerService = activityManagerService;
1888        }
1889
1890        @Override
1891        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1892            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1893                    != PackageManager.PERMISSION_GRANTED) {
1894                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1895                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1896                        + " without permission " + android.Manifest.permission.DUMP);
1897                return;
1898            }
1899
1900            synchronized (mActivityManagerService.mProcessCpuThread) {
1901                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1902                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1903                        SystemClock.uptimeMillis()));
1904            }
1905        }
1906    }
1907
1908    public static final class Lifecycle extends SystemService {
1909        private final ActivityManagerService mService;
1910
1911        public Lifecycle(Context context) {
1912            super(context);
1913            mService = new ActivityManagerService(context);
1914        }
1915
1916        @Override
1917        public void onStart() {
1918            mService.start();
1919        }
1920
1921        public ActivityManagerService getService() {
1922            return mService;
1923        }
1924    }
1925
1926    // Note: This method is invoked on the main thread but may need to attach various
1927    // handlers to other threads.  So take care to be explicit about the looper.
1928    public ActivityManagerService(Context systemContext) {
1929        mContext = systemContext;
1930        mFactoryTest = FactoryTest.getMode();
1931        mSystemThread = ActivityThread.currentActivityThread();
1932
1933        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1934
1935        mHandlerThread = new ServiceThread(TAG,
1936                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1937        mHandlerThread.start();
1938        mHandler = new MainHandler(mHandlerThread.getLooper());
1939
1940        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1941                "foreground", BROADCAST_FG_TIMEOUT, false);
1942        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1943                "background", BROADCAST_BG_TIMEOUT, true);
1944        mBroadcastQueues[0] = mFgBroadcastQueue;
1945        mBroadcastQueues[1] = mBgBroadcastQueue;
1946
1947        mServices = new ActiveServices(this);
1948        mProviderMap = new ProviderMap(this);
1949
1950        // TODO: Move creation of battery stats service outside of activity manager service.
1951        File dataDir = Environment.getDataDirectory();
1952        File systemDir = new File(dataDir, "system");
1953        systemDir.mkdirs();
1954        mBatteryStatsService = new BatteryStatsService(new File(
1955                systemDir, "batterystats.bin").toString(), mHandler);
1956        mBatteryStatsService.getActiveStatistics().readLocked();
1957        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1958        mOnBattery = DEBUG_POWER ? true
1959                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1960        mBatteryStatsService.getActiveStatistics().setCallback(this);
1961
1962        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1963
1964        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1965        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1966
1967        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1968
1969        // User 0 is the first and only user that runs at boot.
1970        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1971        mUserLru.add(Integer.valueOf(0));
1972        updateStartedUserArrayLocked();
1973
1974        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1975            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1976
1977        mConfiguration.setToDefaults();
1978        mConfiguration.setLocale(Locale.getDefault());
1979
1980        mConfigurationSeq = mConfiguration.seq = 1;
1981        mProcessCpuTracker.init();
1982
1983        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1984        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1985        mStackSupervisor = new ActivityStackSupervisor(this);
1986
1987        mProcessCpuThread = new Thread("CpuTracker") {
1988            @Override
1989            public void run() {
1990                while (true) {
1991                    try {
1992                        try {
1993                            synchronized(this) {
1994                                final long now = SystemClock.uptimeMillis();
1995                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1996                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1997                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1998                                //        + ", write delay=" + nextWriteDelay);
1999                                if (nextWriteDelay < nextCpuDelay) {
2000                                    nextCpuDelay = nextWriteDelay;
2001                                }
2002                                if (nextCpuDelay > 0) {
2003                                    mProcessCpuMutexFree.set(true);
2004                                    this.wait(nextCpuDelay);
2005                                }
2006                            }
2007                        } catch (InterruptedException e) {
2008                        }
2009                        updateCpuStatsNow();
2010                    } catch (Exception e) {
2011                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2012                    }
2013                }
2014            }
2015        };
2016
2017        Watchdog.getInstance().addMonitor(this);
2018        Watchdog.getInstance().addThread(mHandler);
2019    }
2020
2021    private void start() {
2022        mProcessCpuThread.start();
2023
2024        mBatteryStatsService.publish(mContext);
2025        mUsageStatsService.publish(mContext);
2026        mAppOpsService.publish(mContext);
2027        startRunning(null, null, null, null);
2028    }
2029
2030    @Override
2031    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2032            throws RemoteException {
2033        if (code == SYSPROPS_TRANSACTION) {
2034            // We need to tell all apps about the system property change.
2035            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2036            synchronized(this) {
2037                final int NP = mProcessNames.getMap().size();
2038                for (int ip=0; ip<NP; ip++) {
2039                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2040                    final int NA = apps.size();
2041                    for (int ia=0; ia<NA; ia++) {
2042                        ProcessRecord app = apps.valueAt(ia);
2043                        if (app.thread != null) {
2044                            procs.add(app.thread.asBinder());
2045                        }
2046                    }
2047                }
2048            }
2049
2050            int N = procs.size();
2051            for (int i=0; i<N; i++) {
2052                Parcel data2 = Parcel.obtain();
2053                try {
2054                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2055                } catch (RemoteException e) {
2056                }
2057                data2.recycle();
2058            }
2059        }
2060        try {
2061            return super.onTransact(code, data, reply, flags);
2062        } catch (RuntimeException e) {
2063            // The activity manager only throws security exceptions, so let's
2064            // log all others.
2065            if (!(e instanceof SecurityException)) {
2066                Slog.wtf(TAG, "Activity Manager Crash", e);
2067            }
2068            throw e;
2069        }
2070    }
2071
2072    void updateCpuStats() {
2073        final long now = SystemClock.uptimeMillis();
2074        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2075            return;
2076        }
2077        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2078            synchronized (mProcessCpuThread) {
2079                mProcessCpuThread.notify();
2080            }
2081        }
2082    }
2083
2084    void updateCpuStatsNow() {
2085        synchronized (mProcessCpuThread) {
2086            mProcessCpuMutexFree.set(false);
2087            final long now = SystemClock.uptimeMillis();
2088            boolean haveNewCpuStats = false;
2089
2090            if (MONITOR_CPU_USAGE &&
2091                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2092                mLastCpuTime.set(now);
2093                haveNewCpuStats = true;
2094                mProcessCpuTracker.update();
2095                //Slog.i(TAG, mProcessCpu.printCurrentState());
2096                //Slog.i(TAG, "Total CPU usage: "
2097                //        + mProcessCpu.getTotalCpuPercent() + "%");
2098
2099                // Slog the cpu usage if the property is set.
2100                if ("true".equals(SystemProperties.get("events.cpu"))) {
2101                    int user = mProcessCpuTracker.getLastUserTime();
2102                    int system = mProcessCpuTracker.getLastSystemTime();
2103                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2104                    int irq = mProcessCpuTracker.getLastIrqTime();
2105                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2106                    int idle = mProcessCpuTracker.getLastIdleTime();
2107
2108                    int total = user + system + iowait + irq + softIrq + idle;
2109                    if (total == 0) total = 1;
2110
2111                    EventLog.writeEvent(EventLogTags.CPU,
2112                            ((user+system+iowait+irq+softIrq) * 100) / total,
2113                            (user * 100) / total,
2114                            (system * 100) / total,
2115                            (iowait * 100) / total,
2116                            (irq * 100) / total,
2117                            (softIrq * 100) / total);
2118                }
2119            }
2120
2121            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2122            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2123            synchronized(bstats) {
2124                synchronized(mPidsSelfLocked) {
2125                    if (haveNewCpuStats) {
2126                        if (mOnBattery) {
2127                            int perc = bstats.startAddingCpuLocked();
2128                            int totalUTime = 0;
2129                            int totalSTime = 0;
2130                            final int N = mProcessCpuTracker.countStats();
2131                            for (int i=0; i<N; i++) {
2132                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2133                                if (!st.working) {
2134                                    continue;
2135                                }
2136                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2137                                int otherUTime = (st.rel_utime*perc)/100;
2138                                int otherSTime = (st.rel_stime*perc)/100;
2139                                totalUTime += otherUTime;
2140                                totalSTime += otherSTime;
2141                                if (pr != null) {
2142                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2143                                    if (ps == null || !ps.isActive()) {
2144                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2145                                                pr.info.uid, pr.processName);
2146                                    }
2147                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2148                                            st.rel_stime-otherSTime);
2149                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2150                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2151                                } else {
2152                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2153                                    if (ps == null || !ps.isActive()) {
2154                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2155                                                bstats.mapUid(st.uid), st.name);
2156                                    }
2157                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2158                                            st.rel_stime-otherSTime);
2159                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2160                                }
2161                            }
2162                            bstats.finishAddingCpuLocked(perc, totalUTime,
2163                                    totalSTime, cpuSpeedTimes);
2164                        }
2165                    }
2166                }
2167
2168                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2169                    mLastWriteTime = now;
2170                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2171                }
2172            }
2173        }
2174    }
2175
2176    @Override
2177    public void batteryNeedsCpuUpdate() {
2178        updateCpuStatsNow();
2179    }
2180
2181    @Override
2182    public void batteryPowerChanged(boolean onBattery) {
2183        // When plugging in, update the CPU stats first before changing
2184        // the plug state.
2185        updateCpuStatsNow();
2186        synchronized (this) {
2187            synchronized(mPidsSelfLocked) {
2188                mOnBattery = DEBUG_POWER ? true : onBattery;
2189            }
2190        }
2191    }
2192
2193    /**
2194     * Initialize the application bind args. These are passed to each
2195     * process when the bindApplication() IPC is sent to the process. They're
2196     * lazily setup to make sure the services are running when they're asked for.
2197     */
2198    private HashMap<String, IBinder> getCommonServicesLocked() {
2199        if (mAppBindArgs == null) {
2200            mAppBindArgs = new HashMap<String, IBinder>();
2201
2202            // Setup the application init args
2203            mAppBindArgs.put("package", ServiceManager.getService("package"));
2204            mAppBindArgs.put("window", ServiceManager.getService("window"));
2205            mAppBindArgs.put(Context.ALARM_SERVICE,
2206                    ServiceManager.getService(Context.ALARM_SERVICE));
2207        }
2208        return mAppBindArgs;
2209    }
2210
2211    final void setFocusedActivityLocked(ActivityRecord r) {
2212        if (mFocusedActivity != r) {
2213            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2214            mFocusedActivity = r;
2215            mStackSupervisor.setFocusedStack(r);
2216            if (r != null) {
2217                mWindowManager.setFocusedApp(r.appToken, true);
2218            }
2219            applyUpdateLockStateLocked(r);
2220        }
2221    }
2222
2223    @Override
2224    public void setFocusedStack(int stackId) {
2225        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2226        synchronized (ActivityManagerService.this) {
2227            ActivityStack stack = mStackSupervisor.getStack(stackId);
2228            if (stack != null) {
2229                ActivityRecord r = stack.topRunningActivityLocked(null);
2230                if (r != null) {
2231                    setFocusedActivityLocked(r);
2232                }
2233            }
2234        }
2235    }
2236
2237    @Override
2238    public void notifyActivityDrawn(IBinder token) {
2239        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2240        synchronized (this) {
2241            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2242            if (r != null) {
2243                r.task.stack.notifyActivityDrawnLocked(r);
2244            }
2245        }
2246    }
2247
2248    final void applyUpdateLockStateLocked(ActivityRecord r) {
2249        // Modifications to the UpdateLock state are done on our handler, outside
2250        // the activity manager's locks.  The new state is determined based on the
2251        // state *now* of the relevant activity record.  The object is passed to
2252        // the handler solely for logging detail, not to be consulted/modified.
2253        final boolean nextState = r != null && r.immersive;
2254        mHandler.sendMessage(
2255                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2256    }
2257
2258    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2259        Message msg = Message.obtain();
2260        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2261        msg.obj = r.task.askedCompatMode ? null : r;
2262        mHandler.sendMessage(msg);
2263    }
2264
2265    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2266            String what, Object obj, ProcessRecord srcApp) {
2267        app.lastActivityTime = now;
2268
2269        if (app.activities.size() > 0) {
2270            // Don't want to touch dependent processes that are hosting activities.
2271            return index;
2272        }
2273
2274        int lrui = mLruProcesses.lastIndexOf(app);
2275        if (lrui < 0) {
2276            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2277                    + what + " " + obj + " from " + srcApp);
2278            return index;
2279        }
2280
2281        if (lrui >= index) {
2282            // Don't want to cause this to move dependent processes *back* in the
2283            // list as if they were less frequently used.
2284            return index;
2285        }
2286
2287        if (lrui >= mLruProcessActivityStart) {
2288            // Don't want to touch dependent processes that are hosting activities.
2289            return index;
2290        }
2291
2292        mLruProcesses.remove(lrui);
2293        if (index > 0) {
2294            index--;
2295        }
2296        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2297                + " in LRU list: " + app);
2298        mLruProcesses.add(index, app);
2299        return index;
2300    }
2301
2302    final void removeLruProcessLocked(ProcessRecord app) {
2303        int lrui = mLruProcesses.lastIndexOf(app);
2304        if (lrui >= 0) {
2305            if (lrui <= mLruProcessActivityStart) {
2306                mLruProcessActivityStart--;
2307            }
2308            if (lrui <= mLruProcessServiceStart) {
2309                mLruProcessServiceStart--;
2310            }
2311            mLruProcesses.remove(lrui);
2312        }
2313    }
2314
2315    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2316            ProcessRecord client) {
2317        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2318        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2319        if (!activityChange && hasActivity) {
2320            // The process has activties, so we are only going to allow activity-based
2321            // adjustments move it.  It should be kept in the front of the list with other
2322            // processes that have activities, and we don't want those to change their
2323            // order except due to activity operations.
2324            return;
2325        }
2326
2327        mLruSeq++;
2328        final long now = SystemClock.uptimeMillis();
2329        app.lastActivityTime = now;
2330
2331        // First a quick reject: if the app is already at the position we will
2332        // put it, then there is nothing to do.
2333        if (hasActivity) {
2334            final int N = mLruProcesses.size();
2335            if (N > 0 && mLruProcesses.get(N-1) == app) {
2336                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2337                return;
2338            }
2339        } else {
2340            if (mLruProcessServiceStart > 0
2341                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2342                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2343                return;
2344            }
2345        }
2346
2347        int lrui = mLruProcesses.lastIndexOf(app);
2348
2349        if (app.persistent && lrui >= 0) {
2350            // We don't care about the position of persistent processes, as long as
2351            // they are in the list.
2352            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2353            return;
2354        }
2355
2356        /* In progress: compute new position first, so we can avoid doing work
2357           if the process is not actually going to move.  Not yet working.
2358        int addIndex;
2359        int nextIndex;
2360        boolean inActivity = false, inService = false;
2361        if (hasActivity) {
2362            // Process has activities, put it at the very tipsy-top.
2363            addIndex = mLruProcesses.size();
2364            nextIndex = mLruProcessServiceStart;
2365            inActivity = true;
2366        } else if (hasService) {
2367            // Process has services, put it at the top of the service list.
2368            addIndex = mLruProcessActivityStart;
2369            nextIndex = mLruProcessServiceStart;
2370            inActivity = true;
2371            inService = true;
2372        } else  {
2373            // Process not otherwise of interest, it goes to the top of the non-service area.
2374            addIndex = mLruProcessServiceStart;
2375            if (client != null) {
2376                int clientIndex = mLruProcesses.lastIndexOf(client);
2377                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2378                        + app);
2379                if (clientIndex >= 0 && addIndex > clientIndex) {
2380                    addIndex = clientIndex;
2381                }
2382            }
2383            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2384        }
2385
2386        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2387                + mLruProcessActivityStart + "): " + app);
2388        */
2389
2390        if (lrui >= 0) {
2391            if (lrui < mLruProcessActivityStart) {
2392                mLruProcessActivityStart--;
2393            }
2394            if (lrui < mLruProcessServiceStart) {
2395                mLruProcessServiceStart--;
2396            }
2397            /*
2398            if (addIndex > lrui) {
2399                addIndex--;
2400            }
2401            if (nextIndex > lrui) {
2402                nextIndex--;
2403            }
2404            */
2405            mLruProcesses.remove(lrui);
2406        }
2407
2408        /*
2409        mLruProcesses.add(addIndex, app);
2410        if (inActivity) {
2411            mLruProcessActivityStart++;
2412        }
2413        if (inService) {
2414            mLruProcessActivityStart++;
2415        }
2416        */
2417
2418        int nextIndex;
2419        if (hasActivity) {
2420            final int N = mLruProcesses.size();
2421            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2422                // Process doesn't have activities, but has clients with
2423                // activities...  move it up, but one below the top (the top
2424                // should always have a real activity).
2425                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2426                mLruProcesses.add(N-1, app);
2427                // To keep it from spamming the LRU list (by making a bunch of clients),
2428                // we will push down any other entries owned by the app.
2429                final int uid = app.info.uid;
2430                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2431                    ProcessRecord subProc = mLruProcesses.get(i);
2432                    if (subProc.info.uid == uid) {
2433                        // We want to push this one down the list.  If the process after
2434                        // it is for the same uid, however, don't do so, because we don't
2435                        // want them internally to be re-ordered.
2436                        if (mLruProcesses.get(i-1).info.uid != uid) {
2437                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2438                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2439                            ProcessRecord tmp = mLruProcesses.get(i);
2440                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2441                            mLruProcesses.set(i-1, tmp);
2442                            i--;
2443                        }
2444                    } else {
2445                        // A gap, we can stop here.
2446                        break;
2447                    }
2448                }
2449            } else {
2450                // Process has activities, put it at the very tipsy-top.
2451                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2452                mLruProcesses.add(app);
2453            }
2454            nextIndex = mLruProcessServiceStart;
2455        } else if (hasService) {
2456            // Process has services, put it at the top of the service list.
2457            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2458            mLruProcesses.add(mLruProcessActivityStart, app);
2459            nextIndex = mLruProcessServiceStart;
2460            mLruProcessActivityStart++;
2461        } else  {
2462            // Process not otherwise of interest, it goes to the top of the non-service area.
2463            int index = mLruProcessServiceStart;
2464            if (client != null) {
2465                // If there is a client, don't allow the process to be moved up higher
2466                // in the list than that client.
2467                int clientIndex = mLruProcesses.lastIndexOf(client);
2468                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2469                        + " when updating " + app);
2470                if (clientIndex <= lrui) {
2471                    // Don't allow the client index restriction to push it down farther in the
2472                    // list than it already is.
2473                    clientIndex = lrui;
2474                }
2475                if (clientIndex >= 0 && index > clientIndex) {
2476                    index = clientIndex;
2477                }
2478            }
2479            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2480            mLruProcesses.add(index, app);
2481            nextIndex = index-1;
2482            mLruProcessActivityStart++;
2483            mLruProcessServiceStart++;
2484        }
2485
2486        // If the app is currently using a content provider or service,
2487        // bump those processes as well.
2488        for (int j=app.connections.size()-1; j>=0; j--) {
2489            ConnectionRecord cr = app.connections.valueAt(j);
2490            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2491                    && cr.binding.service.app != null
2492                    && cr.binding.service.app.lruSeq != mLruSeq
2493                    && !cr.binding.service.app.persistent) {
2494                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2495                        "service connection", cr, app);
2496            }
2497        }
2498        for (int j=app.conProviders.size()-1; j>=0; j--) {
2499            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2500            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2501                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2502                        "provider reference", cpr, app);
2503            }
2504        }
2505    }
2506
2507    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2508        if (uid == Process.SYSTEM_UID) {
2509            // The system gets to run in any process.  If there are multiple
2510            // processes with the same uid, just pick the first (this
2511            // should never happen).
2512            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2513            if (procs == null) return null;
2514            final int N = procs.size();
2515            for (int i = 0; i < N; i++) {
2516                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2517            }
2518        }
2519        ProcessRecord proc = mProcessNames.get(processName, uid);
2520        if (false && proc != null && !keepIfLarge
2521                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2522                && proc.lastCachedPss >= 4000) {
2523            // Turn this condition on to cause killing to happen regularly, for testing.
2524            if (proc.baseProcessTracker != null) {
2525                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2526            }
2527            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2528                    + "k from cached");
2529        } else if (proc != null && !keepIfLarge
2530                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2531                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2532            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2533            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2534                if (proc.baseProcessTracker != null) {
2535                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2536                }
2537                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2538                        + "k from cached");
2539            }
2540        }
2541        return proc;
2542    }
2543
2544    void ensurePackageDexOpt(String packageName) {
2545        IPackageManager pm = AppGlobals.getPackageManager();
2546        try {
2547            if (pm.performDexOpt(packageName)) {
2548                mDidDexOpt = true;
2549            }
2550        } catch (RemoteException e) {
2551        }
2552    }
2553
2554    boolean isNextTransitionForward() {
2555        int transit = mWindowManager.getPendingAppTransition();
2556        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2557                || transit == AppTransition.TRANSIT_TASK_OPEN
2558                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2559    }
2560
2561    final ProcessRecord startProcessLocked(String processName,
2562            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2563            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2564            boolean isolated, boolean keepIfLarge) {
2565        ProcessRecord app;
2566        if (!isolated) {
2567            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2568        } else {
2569            // If this is an isolated process, it can't re-use an existing process.
2570            app = null;
2571        }
2572        // We don't have to do anything more if:
2573        // (1) There is an existing application record; and
2574        // (2) The caller doesn't think it is dead, OR there is no thread
2575        //     object attached to it so we know it couldn't have crashed; and
2576        // (3) There is a pid assigned to it, so it is either starting or
2577        //     already running.
2578        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2579                + " app=" + app + " knownToBeDead=" + knownToBeDead
2580                + " thread=" + (app != null ? app.thread : null)
2581                + " pid=" + (app != null ? app.pid : -1));
2582        if (app != null && app.pid > 0) {
2583            if (!knownToBeDead || app.thread == null) {
2584                // We already have the app running, or are waiting for it to
2585                // come up (we have a pid but not yet its thread), so keep it.
2586                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2587                // If this is a new package in the process, add the package to the list
2588                app.addPackage(info.packageName, mProcessStats);
2589                return app;
2590            }
2591
2592            // An application record is attached to a previous process,
2593            // clean it up now.
2594            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2595            handleAppDiedLocked(app, true, true);
2596        }
2597
2598        String hostingNameStr = hostingName != null
2599                ? hostingName.flattenToShortString() : null;
2600
2601        if (!isolated) {
2602            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2603                // If we are in the background, then check to see if this process
2604                // is bad.  If so, we will just silently fail.
2605                if (mBadProcesses.get(info.processName, info.uid) != null) {
2606                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2607                            + "/" + info.processName);
2608                    return null;
2609                }
2610            } else {
2611                // When the user is explicitly starting a process, then clear its
2612                // crash count so that we won't make it bad until they see at
2613                // least one crash dialog again, and make the process good again
2614                // if it had been bad.
2615                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2616                        + "/" + info.processName);
2617                mProcessCrashTimes.remove(info.processName, info.uid);
2618                if (mBadProcesses.get(info.processName, info.uid) != null) {
2619                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2620                            UserHandle.getUserId(info.uid), info.uid,
2621                            info.processName);
2622                    mBadProcesses.remove(info.processName, info.uid);
2623                    if (app != null) {
2624                        app.bad = false;
2625                    }
2626                }
2627            }
2628        }
2629
2630        if (app == null) {
2631            app = newProcessRecordLocked(info, processName, isolated);
2632            if (app == null) {
2633                Slog.w(TAG, "Failed making new process record for "
2634                        + processName + "/" + info.uid + " isolated=" + isolated);
2635                return null;
2636            }
2637            mProcessNames.put(processName, app.uid, app);
2638            if (isolated) {
2639                mIsolatedProcesses.put(app.uid, app);
2640            }
2641        } else {
2642            // If this is a new package in the process, add the package to the list
2643            app.addPackage(info.packageName, mProcessStats);
2644        }
2645
2646        // If the system is not ready yet, then hold off on starting this
2647        // process until it is.
2648        if (!mProcessesReady
2649                && !isAllowedWhileBooting(info)
2650                && !allowWhileBooting) {
2651            if (!mProcessesOnHold.contains(app)) {
2652                mProcessesOnHold.add(app);
2653            }
2654            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2655            return app;
2656        }
2657
2658        startProcessLocked(app, hostingType, hostingNameStr);
2659        return (app.pid != 0) ? app : null;
2660    }
2661
2662    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2663        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2664    }
2665
2666    private final void startProcessLocked(ProcessRecord app,
2667            String hostingType, String hostingNameStr) {
2668        if (app.pid > 0 && app.pid != MY_PID) {
2669            synchronized (mPidsSelfLocked) {
2670                mPidsSelfLocked.remove(app.pid);
2671                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2672            }
2673            app.setPid(0);
2674        }
2675
2676        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2677                "startProcessLocked removing on hold: " + app);
2678        mProcessesOnHold.remove(app);
2679
2680        updateCpuStats();
2681
2682        try {
2683            int uid = app.uid;
2684
2685            int[] gids = null;
2686            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2687            if (!app.isolated) {
2688                int[] permGids = null;
2689                try {
2690                    final PackageManager pm = mContext.getPackageManager();
2691                    permGids = pm.getPackageGids(app.info.packageName);
2692
2693                    if (Environment.isExternalStorageEmulated()) {
2694                        if (pm.checkPermission(
2695                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2696                                app.info.packageName) == PERMISSION_GRANTED) {
2697                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2698                        } else {
2699                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2700                        }
2701                    }
2702                } catch (PackageManager.NameNotFoundException e) {
2703                    Slog.w(TAG, "Unable to retrieve gids", e);
2704                }
2705
2706                /*
2707                 * Add shared application GID so applications can share some
2708                 * resources like shared libraries
2709                 */
2710                if (permGids == null) {
2711                    gids = new int[1];
2712                } else {
2713                    gids = new int[permGids.length + 1];
2714                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2715                }
2716                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2717            }
2718            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2719                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2720                        && mTopComponent != null
2721                        && app.processName.equals(mTopComponent.getPackageName())) {
2722                    uid = 0;
2723                }
2724                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2725                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2726                    uid = 0;
2727                }
2728            }
2729            int debugFlags = 0;
2730            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2731                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2732                // Also turn on CheckJNI for debuggable apps. It's quite
2733                // awkward to turn on otherwise.
2734                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2735            }
2736            // Run the app in safe mode if its manifest requests so or the
2737            // system is booted in safe mode.
2738            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2739                Zygote.systemInSafeMode == true) {
2740                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2741            }
2742            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2743                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2744            }
2745            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2746                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2747            }
2748            if ("1".equals(SystemProperties.get("debug.assert"))) {
2749                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2750            }
2751
2752            // Start the process.  It will either succeed and return a result containing
2753            // the PID of the new process, or else throw a RuntimeException.
2754            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2755                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2756                    app.info.targetSdkVersion, app.info.seinfo, null);
2757
2758            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2759            synchronized (bs) {
2760                if (bs.isOnBattery()) {
2761                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2762                }
2763            }
2764
2765            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2766                    UserHandle.getUserId(uid), startResult.pid, uid,
2767                    app.processName, hostingType,
2768                    hostingNameStr != null ? hostingNameStr : "");
2769
2770            if (app.persistent) {
2771                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2772            }
2773
2774            StringBuilder buf = mStringBuilder;
2775            buf.setLength(0);
2776            buf.append("Start proc ");
2777            buf.append(app.processName);
2778            buf.append(" for ");
2779            buf.append(hostingType);
2780            if (hostingNameStr != null) {
2781                buf.append(" ");
2782                buf.append(hostingNameStr);
2783            }
2784            buf.append(": pid=");
2785            buf.append(startResult.pid);
2786            buf.append(" uid=");
2787            buf.append(uid);
2788            buf.append(" gids={");
2789            if (gids != null) {
2790                for (int gi=0; gi<gids.length; gi++) {
2791                    if (gi != 0) buf.append(", ");
2792                    buf.append(gids[gi]);
2793
2794                }
2795            }
2796            buf.append("}");
2797            Slog.i(TAG, buf.toString());
2798            app.setPid(startResult.pid);
2799            app.usingWrapper = startResult.usingWrapper;
2800            app.removed = false;
2801            synchronized (mPidsSelfLocked) {
2802                this.mPidsSelfLocked.put(startResult.pid, app);
2803                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2804                msg.obj = app;
2805                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2806                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2807            }
2808            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2809                    app.processName, app.info.uid);
2810            if (app.isolated) {
2811                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2812            }
2813        } catch (RuntimeException e) {
2814            // XXX do better error recovery.
2815            app.setPid(0);
2816            Slog.e(TAG, "Failure starting process " + app.processName, e);
2817        }
2818    }
2819
2820    void updateUsageStats(ActivityRecord component, boolean resumed) {
2821        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2822        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2823        if (resumed) {
2824            mUsageStatsService.noteResumeComponent(component.realActivity);
2825            synchronized (stats) {
2826                stats.noteActivityResumedLocked(component.app.uid);
2827            }
2828        } else {
2829            mUsageStatsService.notePauseComponent(component.realActivity);
2830            synchronized (stats) {
2831                stats.noteActivityPausedLocked(component.app.uid);
2832            }
2833        }
2834    }
2835
2836    Intent getHomeIntent() {
2837        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2838        intent.setComponent(mTopComponent);
2839        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2840            intent.addCategory(Intent.CATEGORY_HOME);
2841        }
2842        return intent;
2843    }
2844
2845    boolean startHomeActivityLocked(int userId) {
2846        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2847                && mTopAction == null) {
2848            // We are running in factory test mode, but unable to find
2849            // the factory test app, so just sit around displaying the
2850            // error message and don't try to start anything.
2851            return false;
2852        }
2853        Intent intent = getHomeIntent();
2854        ActivityInfo aInfo =
2855            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2856        if (aInfo != null) {
2857            intent.setComponent(new ComponentName(
2858                    aInfo.applicationInfo.packageName, aInfo.name));
2859            // Don't do this if the home app is currently being
2860            // instrumented.
2861            aInfo = new ActivityInfo(aInfo);
2862            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2863            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2864                    aInfo.applicationInfo.uid, true);
2865            if (app == null || app.instrumentationClass == null) {
2866                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2867                mStackSupervisor.startHomeActivity(intent, aInfo);
2868            }
2869        }
2870
2871        return true;
2872    }
2873
2874    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2875        ActivityInfo ai = null;
2876        ComponentName comp = intent.getComponent();
2877        try {
2878            if (comp != null) {
2879                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2880            } else {
2881                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2882                        intent,
2883                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2884                            flags, userId);
2885
2886                if (info != null) {
2887                    ai = info.activityInfo;
2888                }
2889            }
2890        } catch (RemoteException e) {
2891            // ignore
2892        }
2893
2894        return ai;
2895    }
2896
2897    /**
2898     * Starts the "new version setup screen" if appropriate.
2899     */
2900    void startSetupActivityLocked() {
2901        // Only do this once per boot.
2902        if (mCheckedForSetup) {
2903            return;
2904        }
2905
2906        // We will show this screen if the current one is a different
2907        // version than the last one shown, and we are not running in
2908        // low-level factory test mode.
2909        final ContentResolver resolver = mContext.getContentResolver();
2910        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2911                Settings.Global.getInt(resolver,
2912                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2913            mCheckedForSetup = true;
2914
2915            // See if we should be showing the platform update setup UI.
2916            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2917            List<ResolveInfo> ris = mContext.getPackageManager()
2918                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2919
2920            // We don't allow third party apps to replace this.
2921            ResolveInfo ri = null;
2922            for (int i=0; ris != null && i<ris.size(); i++) {
2923                if ((ris.get(i).activityInfo.applicationInfo.flags
2924                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2925                    ri = ris.get(i);
2926                    break;
2927                }
2928            }
2929
2930            if (ri != null) {
2931                String vers = ri.activityInfo.metaData != null
2932                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2933                        : null;
2934                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2935                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2936                            Intent.METADATA_SETUP_VERSION);
2937                }
2938                String lastVers = Settings.Secure.getString(
2939                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2940                if (vers != null && !vers.equals(lastVers)) {
2941                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2942                    intent.setComponent(new ComponentName(
2943                            ri.activityInfo.packageName, ri.activityInfo.name));
2944                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2945                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2946                }
2947            }
2948        }
2949    }
2950
2951    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2952        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2953    }
2954
2955    void enforceNotIsolatedCaller(String caller) {
2956        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2957            throw new SecurityException("Isolated process not allowed to call " + caller);
2958        }
2959    }
2960
2961    @Override
2962    public int getFrontActivityScreenCompatMode() {
2963        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2964        synchronized (this) {
2965            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2966        }
2967    }
2968
2969    @Override
2970    public void setFrontActivityScreenCompatMode(int mode) {
2971        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2972                "setFrontActivityScreenCompatMode");
2973        synchronized (this) {
2974            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2975        }
2976    }
2977
2978    @Override
2979    public int getPackageScreenCompatMode(String packageName) {
2980        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2981        synchronized (this) {
2982            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2983        }
2984    }
2985
2986    @Override
2987    public void setPackageScreenCompatMode(String packageName, int mode) {
2988        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2989                "setPackageScreenCompatMode");
2990        synchronized (this) {
2991            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2992        }
2993    }
2994
2995    @Override
2996    public boolean getPackageAskScreenCompat(String packageName) {
2997        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2998        synchronized (this) {
2999            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3000        }
3001    }
3002
3003    @Override
3004    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3005        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3006                "setPackageAskScreenCompat");
3007        synchronized (this) {
3008            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3009        }
3010    }
3011
3012    private void dispatchProcessesChanged() {
3013        int N;
3014        synchronized (this) {
3015            N = mPendingProcessChanges.size();
3016            if (mActiveProcessChanges.length < N) {
3017                mActiveProcessChanges = new ProcessChangeItem[N];
3018            }
3019            mPendingProcessChanges.toArray(mActiveProcessChanges);
3020            mAvailProcessChanges.addAll(mPendingProcessChanges);
3021            mPendingProcessChanges.clear();
3022            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3023        }
3024
3025        int i = mProcessObservers.beginBroadcast();
3026        while (i > 0) {
3027            i--;
3028            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3029            if (observer != null) {
3030                try {
3031                    for (int j=0; j<N; j++) {
3032                        ProcessChangeItem item = mActiveProcessChanges[j];
3033                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3034                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3035                                    + item.pid + " uid=" + item.uid + ": "
3036                                    + item.foregroundActivities);
3037                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3038                                    item.foregroundActivities);
3039                        }
3040                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3041                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3042                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3043                            observer.onImportanceChanged(item.pid, item.uid,
3044                                    item.importance);
3045                        }
3046                    }
3047                } catch (RemoteException e) {
3048                }
3049            }
3050        }
3051        mProcessObservers.finishBroadcast();
3052    }
3053
3054    private void dispatchProcessDied(int pid, int uid) {
3055        int i = mProcessObservers.beginBroadcast();
3056        while (i > 0) {
3057            i--;
3058            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3059            if (observer != null) {
3060                try {
3061                    observer.onProcessDied(pid, uid);
3062                } catch (RemoteException e) {
3063                }
3064            }
3065        }
3066        mProcessObservers.finishBroadcast();
3067    }
3068
3069    final void doPendingActivityLaunchesLocked(boolean doResume) {
3070        final int N = mPendingActivityLaunches.size();
3071        if (N <= 0) {
3072            return;
3073        }
3074        for (int i=0; i<N; i++) {
3075            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3076            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3077                    doResume && i == (N-1), null);
3078        }
3079        mPendingActivityLaunches.clear();
3080    }
3081
3082    @Override
3083    public final int startActivity(IApplicationThread caller, String callingPackage,
3084            Intent intent, String resolvedType, IBinder resultTo,
3085            String resultWho, int requestCode, int startFlags,
3086            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3087        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3088                resultWho, requestCode,
3089                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3090    }
3091
3092    @Override
3093    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3094            Intent intent, String resolvedType, IBinder resultTo,
3095            String resultWho, int requestCode, int startFlags,
3096            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3097        enforceNotIsolatedCaller("startActivity");
3098        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3099                false, true, "startActivity", null);
3100        // TODO: Switch to user app stacks here.
3101        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3102                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3103                null, null, options, userId, null);
3104    }
3105
3106    @Override
3107    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3108            Intent intent, String resolvedType, IBinder resultTo,
3109            String resultWho, int requestCode, int startFlags, String profileFile,
3110            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3111        enforceNotIsolatedCaller("startActivityAndWait");
3112        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3113                false, true, "startActivityAndWait", null);
3114        WaitResult res = new WaitResult();
3115        // TODO: Switch to user app stacks here.
3116        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3117                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3118                res, null, options, UserHandle.getCallingUserId(), null);
3119        return res;
3120    }
3121
3122    @Override
3123    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3124            Intent intent, String resolvedType, IBinder resultTo,
3125            String resultWho, int requestCode, int startFlags, Configuration config,
3126            Bundle options, int userId) {
3127        enforceNotIsolatedCaller("startActivityWithConfig");
3128        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3129                false, true, "startActivityWithConfig", null);
3130        // TODO: Switch to user app stacks here.
3131        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3132                resolvedType, resultTo, resultWho, requestCode, startFlags,
3133                null, null, null, config, options, userId, null);
3134        return ret;
3135    }
3136
3137    @Override
3138    public int startActivityIntentSender(IApplicationThread caller,
3139            IntentSender intent, Intent fillInIntent, String resolvedType,
3140            IBinder resultTo, String resultWho, int requestCode,
3141            int flagsMask, int flagsValues, Bundle options) {
3142        enforceNotIsolatedCaller("startActivityIntentSender");
3143        // Refuse possible leaked file descriptors
3144        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3145            throw new IllegalArgumentException("File descriptors passed in Intent");
3146        }
3147
3148        IIntentSender sender = intent.getTarget();
3149        if (!(sender instanceof PendingIntentRecord)) {
3150            throw new IllegalArgumentException("Bad PendingIntent object");
3151        }
3152
3153        PendingIntentRecord pir = (PendingIntentRecord)sender;
3154
3155        synchronized (this) {
3156            // If this is coming from the currently resumed activity, it is
3157            // effectively saying that app switches are allowed at this point.
3158            final ActivityStack stack = getFocusedStack();
3159            if (stack.mResumedActivity != null &&
3160                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3161                mAppSwitchesAllowedTime = 0;
3162            }
3163        }
3164        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3165                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3166        return ret;
3167    }
3168
3169    @Override
3170    public boolean startNextMatchingActivity(IBinder callingActivity,
3171            Intent intent, Bundle options) {
3172        // Refuse possible leaked file descriptors
3173        if (intent != null && intent.hasFileDescriptors() == true) {
3174            throw new IllegalArgumentException("File descriptors passed in Intent");
3175        }
3176
3177        synchronized (this) {
3178            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3179            if (r == null) {
3180                ActivityOptions.abort(options);
3181                return false;
3182            }
3183            if (r.app == null || r.app.thread == null) {
3184                // The caller is not running...  d'oh!
3185                ActivityOptions.abort(options);
3186                return false;
3187            }
3188            intent = new Intent(intent);
3189            // The caller is not allowed to change the data.
3190            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3191            // And we are resetting to find the next component...
3192            intent.setComponent(null);
3193
3194            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3195
3196            ActivityInfo aInfo = null;
3197            try {
3198                List<ResolveInfo> resolves =
3199                    AppGlobals.getPackageManager().queryIntentActivities(
3200                            intent, r.resolvedType,
3201                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3202                            UserHandle.getCallingUserId());
3203
3204                // Look for the original activity in the list...
3205                final int N = resolves != null ? resolves.size() : 0;
3206                for (int i=0; i<N; i++) {
3207                    ResolveInfo rInfo = resolves.get(i);
3208                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3209                            && rInfo.activityInfo.name.equals(r.info.name)) {
3210                        // We found the current one...  the next matching is
3211                        // after it.
3212                        i++;
3213                        if (i<N) {
3214                            aInfo = resolves.get(i).activityInfo;
3215                        }
3216                        if (debug) {
3217                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3218                                    + "/" + r.info.name);
3219                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3220                                    + "/" + aInfo.name);
3221                        }
3222                        break;
3223                    }
3224                }
3225            } catch (RemoteException e) {
3226            }
3227
3228            if (aInfo == null) {
3229                // Nobody who is next!
3230                ActivityOptions.abort(options);
3231                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3232                return false;
3233            }
3234
3235            intent.setComponent(new ComponentName(
3236                    aInfo.applicationInfo.packageName, aInfo.name));
3237            intent.setFlags(intent.getFlags()&~(
3238                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3239                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3240                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3241                    Intent.FLAG_ACTIVITY_NEW_TASK));
3242
3243            // Okay now we need to start the new activity, replacing the
3244            // currently running activity.  This is a little tricky because
3245            // we want to start the new one as if the current one is finished,
3246            // but not finish the current one first so that there is no flicker.
3247            // And thus...
3248            final boolean wasFinishing = r.finishing;
3249            r.finishing = true;
3250
3251            // Propagate reply information over to the new activity.
3252            final ActivityRecord resultTo = r.resultTo;
3253            final String resultWho = r.resultWho;
3254            final int requestCode = r.requestCode;
3255            r.resultTo = null;
3256            if (resultTo != null) {
3257                resultTo.removeResultsLocked(r, resultWho, requestCode);
3258            }
3259
3260            final long origId = Binder.clearCallingIdentity();
3261            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3262                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3263                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3264                    options, false, null, null);
3265            Binder.restoreCallingIdentity(origId);
3266
3267            r.finishing = wasFinishing;
3268            if (res != ActivityManager.START_SUCCESS) {
3269                return false;
3270            }
3271            return true;
3272        }
3273    }
3274
3275    final int startActivityInPackage(int uid, String callingPackage,
3276            Intent intent, String resolvedType, IBinder resultTo,
3277            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3278                    IActivityContainer container) {
3279
3280        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3281                false, true, "startActivityInPackage", null);
3282
3283        // TODO: Switch to user app stacks here.
3284        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3285                resultTo, resultWho, requestCode, startFlags,
3286                null, null, null, null, options, userId, container);
3287        return ret;
3288    }
3289
3290    @Override
3291    public final int startActivities(IApplicationThread caller, String callingPackage,
3292            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3293            int userId) {
3294        enforceNotIsolatedCaller("startActivities");
3295        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3296                false, true, "startActivity", null);
3297        // TODO: Switch to user app stacks here.
3298        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3299                resolvedTypes, resultTo, options, userId);
3300        return ret;
3301    }
3302
3303    final int startActivitiesInPackage(int uid, String callingPackage,
3304            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3305            Bundle options, int userId) {
3306
3307        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3308                false, true, "startActivityInPackage", null);
3309        // TODO: Switch to user app stacks here.
3310        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3311                resultTo, options, userId);
3312        return ret;
3313    }
3314
3315    final void addRecentTaskLocked(TaskRecord task) {
3316        int N = mRecentTasks.size();
3317        // Quick case: check if the top-most recent task is the same.
3318        if (N > 0 && mRecentTasks.get(0) == task) {
3319            return;
3320        }
3321        // Remove any existing entries that are the same kind of task.
3322        for (int i=0; i<N; i++) {
3323            TaskRecord tr = mRecentTasks.get(i);
3324            if (task.userId == tr.userId
3325                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3326                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3327                tr.disposeThumbnail();
3328                mRecentTasks.remove(i);
3329                i--;
3330                N--;
3331                if (task.intent == null) {
3332                    // If the new recent task we are adding is not fully
3333                    // specified, then replace it with the existing recent task.
3334                    task = tr;
3335                }
3336            }
3337        }
3338        if (N >= MAX_RECENT_TASKS) {
3339            mRecentTasks.remove(N-1).disposeThumbnail();
3340        }
3341        mRecentTasks.add(0, task);
3342    }
3343
3344    @Override
3345    public void reportActivityFullyDrawn(IBinder token) {
3346        synchronized (this) {
3347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3348            if (r == null) {
3349                return;
3350            }
3351            r.reportFullyDrawnLocked();
3352        }
3353    }
3354
3355    @Override
3356    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3357        synchronized (this) {
3358            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3359            if (r == null) {
3360                return;
3361            }
3362            final long origId = Binder.clearCallingIdentity();
3363            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3364            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3365                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3366            if (config != null) {
3367                r.frozenBeforeDestroy = true;
3368                if (!updateConfigurationLocked(config, r, false, false)) {
3369                    mStackSupervisor.resumeTopActivitiesLocked();
3370                }
3371            }
3372            Binder.restoreCallingIdentity(origId);
3373        }
3374    }
3375
3376    @Override
3377    public int getRequestedOrientation(IBinder token) {
3378        synchronized (this) {
3379            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3380            if (r == null) {
3381                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3382            }
3383            return mWindowManager.getAppOrientation(r.appToken);
3384        }
3385    }
3386
3387    /**
3388     * This is the internal entry point for handling Activity.finish().
3389     *
3390     * @param token The Binder token referencing the Activity we want to finish.
3391     * @param resultCode Result code, if any, from this Activity.
3392     * @param resultData Result data (Intent), if any, from this Activity.
3393     *
3394     * @return Returns true if the activity successfully finished, or false if it is still running.
3395     */
3396    @Override
3397    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3398        // Refuse possible leaked file descriptors
3399        if (resultData != null && resultData.hasFileDescriptors() == true) {
3400            throw new IllegalArgumentException("File descriptors passed in Intent");
3401        }
3402
3403        synchronized(this) {
3404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3405            if (r == null) {
3406                return true;
3407            }
3408            if (mController != null) {
3409                // Find the first activity that is not finishing.
3410                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3411                if (next != null) {
3412                    // ask watcher if this is allowed
3413                    boolean resumeOK = true;
3414                    try {
3415                        resumeOK = mController.activityResuming(next.packageName);
3416                    } catch (RemoteException e) {
3417                        mController = null;
3418                        Watchdog.getInstance().setActivityController(null);
3419                    }
3420
3421                    if (!resumeOK) {
3422                        return false;
3423                    }
3424                }
3425            }
3426            final long origId = Binder.clearCallingIdentity();
3427            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3428                    resultData, "app-request", true);
3429            Binder.restoreCallingIdentity(origId);
3430            return res;
3431        }
3432    }
3433
3434    @Override
3435    public final void finishHeavyWeightApp() {
3436        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3437                != PackageManager.PERMISSION_GRANTED) {
3438            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3439                    + Binder.getCallingPid()
3440                    + ", uid=" + Binder.getCallingUid()
3441                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3442            Slog.w(TAG, msg);
3443            throw new SecurityException(msg);
3444        }
3445
3446        synchronized(this) {
3447            if (mHeavyWeightProcess == null) {
3448                return;
3449            }
3450
3451            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3452                    mHeavyWeightProcess.activities);
3453            for (int i=0; i<activities.size(); i++) {
3454                ActivityRecord r = activities.get(i);
3455                if (!r.finishing) {
3456                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3457                            null, "finish-heavy", true);
3458                }
3459            }
3460
3461            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3462                    mHeavyWeightProcess.userId, 0));
3463            mHeavyWeightProcess = null;
3464        }
3465    }
3466
3467    @Override
3468    public void crashApplication(int uid, int initialPid, String packageName,
3469            String message) {
3470        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3471                != PackageManager.PERMISSION_GRANTED) {
3472            String msg = "Permission Denial: crashApplication() from pid="
3473                    + Binder.getCallingPid()
3474                    + ", uid=" + Binder.getCallingUid()
3475                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3476            Slog.w(TAG, msg);
3477            throw new SecurityException(msg);
3478        }
3479
3480        synchronized(this) {
3481            ProcessRecord proc = null;
3482
3483            // Figure out which process to kill.  We don't trust that initialPid
3484            // still has any relation to current pids, so must scan through the
3485            // list.
3486            synchronized (mPidsSelfLocked) {
3487                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3488                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3489                    if (p.uid != uid) {
3490                        continue;
3491                    }
3492                    if (p.pid == initialPid) {
3493                        proc = p;
3494                        break;
3495                    }
3496                    if (p.pkgList.containsKey(packageName)) {
3497                        proc = p;
3498                    }
3499                }
3500            }
3501
3502            if (proc == null) {
3503                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3504                        + " initialPid=" + initialPid
3505                        + " packageName=" + packageName);
3506                return;
3507            }
3508
3509            if (proc.thread != null) {
3510                if (proc.pid == Process.myPid()) {
3511                    Log.w(TAG, "crashApplication: trying to crash self!");
3512                    return;
3513                }
3514                long ident = Binder.clearCallingIdentity();
3515                try {
3516                    proc.thread.scheduleCrash(message);
3517                } catch (RemoteException e) {
3518                }
3519                Binder.restoreCallingIdentity(ident);
3520            }
3521        }
3522    }
3523
3524    @Override
3525    public final void finishSubActivity(IBinder token, String resultWho,
3526            int requestCode) {
3527        synchronized(this) {
3528            final long origId = Binder.clearCallingIdentity();
3529            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3530            if (r != null) {
3531                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3532            }
3533            Binder.restoreCallingIdentity(origId);
3534        }
3535    }
3536
3537    @Override
3538    public boolean finishActivityAffinity(IBinder token) {
3539        synchronized(this) {
3540            final long origId = Binder.clearCallingIdentity();
3541            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3542            boolean res = false;
3543            if (r != null) {
3544                res = r.task.stack.finishActivityAffinityLocked(r);
3545            }
3546            Binder.restoreCallingIdentity(origId);
3547            return res;
3548        }
3549    }
3550
3551    @Override
3552    public boolean willActivityBeVisible(IBinder token) {
3553        synchronized(this) {
3554            ActivityStack stack = ActivityRecord.getStackLocked(token);
3555            if (stack != null) {
3556                return stack.willActivityBeVisibleLocked(token);
3557            }
3558            return false;
3559        }
3560    }
3561
3562    @Override
3563    public void overridePendingTransition(IBinder token, String packageName,
3564            int enterAnim, int exitAnim) {
3565        synchronized(this) {
3566            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3567            if (self == null) {
3568                return;
3569            }
3570
3571            final long origId = Binder.clearCallingIdentity();
3572
3573            if (self.state == ActivityState.RESUMED
3574                    || self.state == ActivityState.PAUSING) {
3575                mWindowManager.overridePendingAppTransition(packageName,
3576                        enterAnim, exitAnim, null);
3577            }
3578
3579            Binder.restoreCallingIdentity(origId);
3580        }
3581    }
3582
3583    /**
3584     * Main function for removing an existing process from the activity manager
3585     * as a result of that process going away.  Clears out all connections
3586     * to the process.
3587     */
3588    private final void handleAppDiedLocked(ProcessRecord app,
3589            boolean restarting, boolean allowRestart) {
3590        int pid = app.pid;
3591        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3592        if (!restarting) {
3593            removeLruProcessLocked(app);
3594            if (pid > 0) {
3595                ProcessList.remove(pid);
3596            }
3597        }
3598
3599        if (mProfileProc == app) {
3600            clearProfilerLocked();
3601        }
3602
3603        // Remove this application's activities from active lists.
3604        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3605
3606        app.activities.clear();
3607
3608        if (app.instrumentationClass != null) {
3609            Slog.w(TAG, "Crash of app " + app.processName
3610                  + " running instrumentation " + app.instrumentationClass);
3611            Bundle info = new Bundle();
3612            info.putString("shortMsg", "Process crashed.");
3613            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3614        }
3615
3616        if (!restarting) {
3617            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3618                // If there was nothing to resume, and we are not already
3619                // restarting this process, but there is a visible activity that
3620                // is hosted by the process...  then make sure all visible
3621                // activities are running, taking care of restarting this
3622                // process.
3623                if (hasVisibleActivities) {
3624                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3625                }
3626            }
3627        }
3628    }
3629
3630    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3631        IBinder threadBinder = thread.asBinder();
3632        // Find the application record.
3633        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3634            ProcessRecord rec = mLruProcesses.get(i);
3635            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3636                return i;
3637            }
3638        }
3639        return -1;
3640    }
3641
3642    final ProcessRecord getRecordForAppLocked(
3643            IApplicationThread thread) {
3644        if (thread == null) {
3645            return null;
3646        }
3647
3648        int appIndex = getLRURecordIndexForAppLocked(thread);
3649        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3650    }
3651
3652    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3653        // If there are no longer any background processes running,
3654        // and the app that died was not running instrumentation,
3655        // then tell everyone we are now low on memory.
3656        boolean haveBg = false;
3657        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3658            ProcessRecord rec = mLruProcesses.get(i);
3659            if (rec.thread != null
3660                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3661                haveBg = true;
3662                break;
3663            }
3664        }
3665
3666        if (!haveBg) {
3667            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3668            if (doReport) {
3669                long now = SystemClock.uptimeMillis();
3670                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3671                    doReport = false;
3672                } else {
3673                    mLastMemUsageReportTime = now;
3674                }
3675            }
3676            final ArrayList<ProcessMemInfo> memInfos
3677                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3678            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3679            long now = SystemClock.uptimeMillis();
3680            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3681                ProcessRecord rec = mLruProcesses.get(i);
3682                if (rec == dyingProc || rec.thread == null) {
3683                    continue;
3684                }
3685                if (doReport) {
3686                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3687                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3688                }
3689                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3690                    // The low memory report is overriding any current
3691                    // state for a GC request.  Make sure to do
3692                    // heavy/important/visible/foreground processes first.
3693                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3694                        rec.lastRequestedGc = 0;
3695                    } else {
3696                        rec.lastRequestedGc = rec.lastLowMemory;
3697                    }
3698                    rec.reportLowMemory = true;
3699                    rec.lastLowMemory = now;
3700                    mProcessesToGc.remove(rec);
3701                    addProcessToGcListLocked(rec);
3702                }
3703            }
3704            if (doReport) {
3705                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3706                mHandler.sendMessage(msg);
3707            }
3708            scheduleAppGcsLocked();
3709        }
3710    }
3711
3712    final void appDiedLocked(ProcessRecord app, int pid,
3713            IApplicationThread thread) {
3714
3715        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3716        synchronized (stats) {
3717            stats.noteProcessDiedLocked(app.info.uid, pid);
3718        }
3719
3720        // Clean up already done if the process has been re-started.
3721        if (app.pid == pid && app.thread != null &&
3722                app.thread.asBinder() == thread.asBinder()) {
3723            boolean doLowMem = app.instrumentationClass == null;
3724            boolean doOomAdj = doLowMem;
3725            if (!app.killedByAm) {
3726                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3727                        + ") has died.");
3728                mAllowLowerMemLevel = true;
3729            } else {
3730                // Note that we always want to do oom adj to update our state with the
3731                // new number of procs.
3732                mAllowLowerMemLevel = false;
3733                doLowMem = false;
3734            }
3735            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3736            if (DEBUG_CLEANUP) Slog.v(
3737                TAG, "Dying app: " + app + ", pid: " + pid
3738                + ", thread: " + thread.asBinder());
3739            handleAppDiedLocked(app, false, true);
3740
3741            if (doOomAdj) {
3742                updateOomAdjLocked();
3743            }
3744            if (doLowMem) {
3745                doLowMemReportIfNeededLocked(app);
3746            }
3747        } else if (app.pid != pid) {
3748            // A new process has already been started.
3749            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3750                    + ") has died and restarted (pid " + app.pid + ").");
3751            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3752        } else if (DEBUG_PROCESSES) {
3753            Slog.d(TAG, "Received spurious death notification for thread "
3754                    + thread.asBinder());
3755        }
3756    }
3757
3758    /**
3759     * If a stack trace dump file is configured, dump process stack traces.
3760     * @param clearTraces causes the dump file to be erased prior to the new
3761     *    traces being written, if true; when false, the new traces will be
3762     *    appended to any existing file content.
3763     * @param firstPids of dalvik VM processes to dump stack traces for first
3764     * @param lastPids of dalvik VM processes to dump stack traces for last
3765     * @param nativeProcs optional list of native process names to dump stack crawls
3766     * @return file containing stack traces, or null if no dump file is configured
3767     */
3768    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3769            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3770        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3771        if (tracesPath == null || tracesPath.length() == 0) {
3772            return null;
3773        }
3774
3775        File tracesFile = new File(tracesPath);
3776        try {
3777            File tracesDir = tracesFile.getParentFile();
3778            if (!tracesDir.exists()) {
3779                tracesFile.mkdirs();
3780                if (!SELinux.restorecon(tracesDir)) {
3781                    return null;
3782                }
3783            }
3784            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3785
3786            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3787            tracesFile.createNewFile();
3788            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3789        } catch (IOException e) {
3790            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3791            return null;
3792        }
3793
3794        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3795        return tracesFile;
3796    }
3797
3798    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3799            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3800        // Use a FileObserver to detect when traces finish writing.
3801        // The order of traces is considered important to maintain for legibility.
3802        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3803            @Override
3804            public synchronized void onEvent(int event, String path) { notify(); }
3805        };
3806
3807        try {
3808            observer.startWatching();
3809
3810            // First collect all of the stacks of the most important pids.
3811            if (firstPids != null) {
3812                try {
3813                    int num = firstPids.size();
3814                    for (int i = 0; i < num; i++) {
3815                        synchronized (observer) {
3816                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3817                            observer.wait(200);  // Wait for write-close, give up after 200msec
3818                        }
3819                    }
3820                } catch (InterruptedException e) {
3821                    Log.wtf(TAG, e);
3822                }
3823            }
3824
3825            // Next collect the stacks of the native pids
3826            if (nativeProcs != null) {
3827                int[] pids = Process.getPidsForCommands(nativeProcs);
3828                if (pids != null) {
3829                    for (int pid : pids) {
3830                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3831                    }
3832                }
3833            }
3834
3835            // Lastly, measure CPU usage.
3836            if (processCpuTracker != null) {
3837                processCpuTracker.init();
3838                System.gc();
3839                processCpuTracker.update();
3840                try {
3841                    synchronized (processCpuTracker) {
3842                        processCpuTracker.wait(500); // measure over 1/2 second.
3843                    }
3844                } catch (InterruptedException e) {
3845                }
3846                processCpuTracker.update();
3847
3848                // We'll take the stack crawls of just the top apps using CPU.
3849                final int N = processCpuTracker.countWorkingStats();
3850                int numProcs = 0;
3851                for (int i=0; i<N && numProcs<5; i++) {
3852                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3853                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3854                        numProcs++;
3855                        try {
3856                            synchronized (observer) {
3857                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3858                                observer.wait(200);  // Wait for write-close, give up after 200msec
3859                            }
3860                        } catch (InterruptedException e) {
3861                            Log.wtf(TAG, e);
3862                        }
3863
3864                    }
3865                }
3866            }
3867        } finally {
3868            observer.stopWatching();
3869        }
3870    }
3871
3872    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3873        if (true || IS_USER_BUILD) {
3874            return;
3875        }
3876        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3877        if (tracesPath == null || tracesPath.length() == 0) {
3878            return;
3879        }
3880
3881        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3882        StrictMode.allowThreadDiskWrites();
3883        try {
3884            final File tracesFile = new File(tracesPath);
3885            final File tracesDir = tracesFile.getParentFile();
3886            final File tracesTmp = new File(tracesDir, "__tmp__");
3887            try {
3888                if (!tracesDir.exists()) {
3889                    tracesFile.mkdirs();
3890                    if (!SELinux.restorecon(tracesDir.getPath())) {
3891                        return;
3892                    }
3893                }
3894                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3895
3896                if (tracesFile.exists()) {
3897                    tracesTmp.delete();
3898                    tracesFile.renameTo(tracesTmp);
3899                }
3900                StringBuilder sb = new StringBuilder();
3901                Time tobj = new Time();
3902                tobj.set(System.currentTimeMillis());
3903                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3904                sb.append(": ");
3905                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3906                sb.append(" since ");
3907                sb.append(msg);
3908                FileOutputStream fos = new FileOutputStream(tracesFile);
3909                fos.write(sb.toString().getBytes());
3910                if (app == null) {
3911                    fos.write("\n*** No application process!".getBytes());
3912                }
3913                fos.close();
3914                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3915            } catch (IOException e) {
3916                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3917                return;
3918            }
3919
3920            if (app != null) {
3921                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3922                firstPids.add(app.pid);
3923                dumpStackTraces(tracesPath, firstPids, null, null, null);
3924            }
3925
3926            File lastTracesFile = null;
3927            File curTracesFile = null;
3928            for (int i=9; i>=0; i--) {
3929                String name = String.format(Locale.US, "slow%02d.txt", i);
3930                curTracesFile = new File(tracesDir, name);
3931                if (curTracesFile.exists()) {
3932                    if (lastTracesFile != null) {
3933                        curTracesFile.renameTo(lastTracesFile);
3934                    } else {
3935                        curTracesFile.delete();
3936                    }
3937                }
3938                lastTracesFile = curTracesFile;
3939            }
3940            tracesFile.renameTo(curTracesFile);
3941            if (tracesTmp.exists()) {
3942                tracesTmp.renameTo(tracesFile);
3943            }
3944        } finally {
3945            StrictMode.setThreadPolicy(oldPolicy);
3946        }
3947    }
3948
3949    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3950            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3951        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3952        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3953
3954        if (mController != null) {
3955            try {
3956                // 0 == continue, -1 = kill process immediately
3957                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3958                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3959            } catch (RemoteException e) {
3960                mController = null;
3961                Watchdog.getInstance().setActivityController(null);
3962            }
3963        }
3964
3965        long anrTime = SystemClock.uptimeMillis();
3966        if (MONITOR_CPU_USAGE) {
3967            updateCpuStatsNow();
3968        }
3969
3970        synchronized (this) {
3971            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3972            if (mShuttingDown) {
3973                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3974                return;
3975            } else if (app.notResponding) {
3976                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3977                return;
3978            } else if (app.crashing) {
3979                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3980                return;
3981            }
3982
3983            // In case we come through here for the same app before completing
3984            // this one, mark as anring now so we will bail out.
3985            app.notResponding = true;
3986
3987            // Log the ANR to the event log.
3988            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3989                    app.processName, app.info.flags, annotation);
3990
3991            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3992            firstPids.add(app.pid);
3993
3994            int parentPid = app.pid;
3995            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3996            if (parentPid != app.pid) firstPids.add(parentPid);
3997
3998            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3999
4000            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4001                ProcessRecord r = mLruProcesses.get(i);
4002                if (r != null && r.thread != null) {
4003                    int pid = r.pid;
4004                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4005                        if (r.persistent) {
4006                            firstPids.add(pid);
4007                        } else {
4008                            lastPids.put(pid, Boolean.TRUE);
4009                        }
4010                    }
4011                }
4012            }
4013        }
4014
4015        // Log the ANR to the main log.
4016        StringBuilder info = new StringBuilder();
4017        info.setLength(0);
4018        info.append("ANR in ").append(app.processName);
4019        if (activity != null && activity.shortComponentName != null) {
4020            info.append(" (").append(activity.shortComponentName).append(")");
4021        }
4022        info.append("\n");
4023        info.append("PID: ").append(app.pid).append("\n");
4024        if (annotation != null) {
4025            info.append("Reason: ").append(annotation).append("\n");
4026        }
4027        if (parent != null && parent != activity) {
4028            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4029        }
4030
4031        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4032
4033        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4034                NATIVE_STACKS_OF_INTEREST);
4035
4036        String cpuInfo = null;
4037        if (MONITOR_CPU_USAGE) {
4038            updateCpuStatsNow();
4039            synchronized (mProcessCpuThread) {
4040                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4041            }
4042            info.append(processCpuTracker.printCurrentLoad());
4043            info.append(cpuInfo);
4044        }
4045
4046        info.append(processCpuTracker.printCurrentState(anrTime));
4047
4048        Slog.e(TAG, info.toString());
4049        if (tracesFile == null) {
4050            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4051            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4052        }
4053
4054        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4055                cpuInfo, tracesFile, null);
4056
4057        if (mController != null) {
4058            try {
4059                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4060                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4061                if (res != 0) {
4062                    if (res < 0 && app.pid != MY_PID) {
4063                        Process.killProcess(app.pid);
4064                    } else {
4065                        synchronized (this) {
4066                            mServices.scheduleServiceTimeoutLocked(app);
4067                        }
4068                    }
4069                    return;
4070                }
4071            } catch (RemoteException e) {
4072                mController = null;
4073                Watchdog.getInstance().setActivityController(null);
4074            }
4075        }
4076
4077        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4078        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4079                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4080
4081        synchronized (this) {
4082            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4083                killUnneededProcessLocked(app, "background ANR");
4084                return;
4085            }
4086
4087            // Set the app's notResponding state, and look up the errorReportReceiver
4088            makeAppNotRespondingLocked(app,
4089                    activity != null ? activity.shortComponentName : null,
4090                    annotation != null ? "ANR " + annotation : "ANR",
4091                    info.toString());
4092
4093            // Bring up the infamous App Not Responding dialog
4094            Message msg = Message.obtain();
4095            HashMap<String, Object> map = new HashMap<String, Object>();
4096            msg.what = SHOW_NOT_RESPONDING_MSG;
4097            msg.obj = map;
4098            msg.arg1 = aboveSystem ? 1 : 0;
4099            map.put("app", app);
4100            if (activity != null) {
4101                map.put("activity", activity);
4102            }
4103
4104            mHandler.sendMessage(msg);
4105        }
4106    }
4107
4108    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4109        if (!mLaunchWarningShown) {
4110            mLaunchWarningShown = true;
4111            mHandler.post(new Runnable() {
4112                @Override
4113                public void run() {
4114                    synchronized (ActivityManagerService.this) {
4115                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4116                        d.show();
4117                        mHandler.postDelayed(new Runnable() {
4118                            @Override
4119                            public void run() {
4120                                synchronized (ActivityManagerService.this) {
4121                                    d.dismiss();
4122                                    mLaunchWarningShown = false;
4123                                }
4124                            }
4125                        }, 4000);
4126                    }
4127                }
4128            });
4129        }
4130    }
4131
4132    @Override
4133    public boolean clearApplicationUserData(final String packageName,
4134            final IPackageDataObserver observer, int userId) {
4135        enforceNotIsolatedCaller("clearApplicationUserData");
4136        int uid = Binder.getCallingUid();
4137        int pid = Binder.getCallingPid();
4138        userId = handleIncomingUser(pid, uid,
4139                userId, false, true, "clearApplicationUserData", null);
4140        long callingId = Binder.clearCallingIdentity();
4141        try {
4142            IPackageManager pm = AppGlobals.getPackageManager();
4143            int pkgUid = -1;
4144            synchronized(this) {
4145                try {
4146                    pkgUid = pm.getPackageUid(packageName, userId);
4147                } catch (RemoteException e) {
4148                }
4149                if (pkgUid == -1) {
4150                    Slog.w(TAG, "Invalid packageName: " + packageName);
4151                    if (observer != null) {
4152                        try {
4153                            observer.onRemoveCompleted(packageName, false);
4154                        } catch (RemoteException e) {
4155                            Slog.i(TAG, "Observer no longer exists.");
4156                        }
4157                    }
4158                    return false;
4159                }
4160                if (uid == pkgUid || checkComponentPermission(
4161                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4162                        pid, uid, -1, true)
4163                        == PackageManager.PERMISSION_GRANTED) {
4164                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4165                } else {
4166                    throw new SecurityException("PID " + pid + " does not have permission "
4167                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4168                                    + " of package " + packageName);
4169                }
4170            }
4171
4172            try {
4173                // Clear application user data
4174                pm.clearApplicationUserData(packageName, observer, userId);
4175
4176                // Remove all permissions granted from/to this package
4177                removeUriPermissionsForPackageLocked(packageName, userId, true);
4178
4179                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4180                        Uri.fromParts("package", packageName, null));
4181                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4182                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4183                        null, null, 0, null, null, null, false, false, userId);
4184            } catch (RemoteException e) {
4185            }
4186        } finally {
4187            Binder.restoreCallingIdentity(callingId);
4188        }
4189        return true;
4190    }
4191
4192    @Override
4193    public void killBackgroundProcesses(final String packageName, int userId) {
4194        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4195                != PackageManager.PERMISSION_GRANTED &&
4196                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4197                        != PackageManager.PERMISSION_GRANTED) {
4198            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4199                    + Binder.getCallingPid()
4200                    + ", uid=" + Binder.getCallingUid()
4201                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4202            Slog.w(TAG, msg);
4203            throw new SecurityException(msg);
4204        }
4205
4206        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4207                userId, true, true, "killBackgroundProcesses", null);
4208        long callingId = Binder.clearCallingIdentity();
4209        try {
4210            IPackageManager pm = AppGlobals.getPackageManager();
4211            synchronized(this) {
4212                int appId = -1;
4213                try {
4214                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4215                } catch (RemoteException e) {
4216                }
4217                if (appId == -1) {
4218                    Slog.w(TAG, "Invalid packageName: " + packageName);
4219                    return;
4220                }
4221                killPackageProcessesLocked(packageName, appId, userId,
4222                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4223            }
4224        } finally {
4225            Binder.restoreCallingIdentity(callingId);
4226        }
4227    }
4228
4229    @Override
4230    public void killAllBackgroundProcesses() {
4231        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4232                != PackageManager.PERMISSION_GRANTED) {
4233            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4234                    + Binder.getCallingPid()
4235                    + ", uid=" + Binder.getCallingUid()
4236                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4237            Slog.w(TAG, msg);
4238            throw new SecurityException(msg);
4239        }
4240
4241        long callingId = Binder.clearCallingIdentity();
4242        try {
4243            synchronized(this) {
4244                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4245                final int NP = mProcessNames.getMap().size();
4246                for (int ip=0; ip<NP; ip++) {
4247                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4248                    final int NA = apps.size();
4249                    for (int ia=0; ia<NA; ia++) {
4250                        ProcessRecord app = apps.valueAt(ia);
4251                        if (app.persistent) {
4252                            // we don't kill persistent processes
4253                            continue;
4254                        }
4255                        if (app.removed) {
4256                            procs.add(app);
4257                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4258                            app.removed = true;
4259                            procs.add(app);
4260                        }
4261                    }
4262                }
4263
4264                int N = procs.size();
4265                for (int i=0; i<N; i++) {
4266                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4267                }
4268                mAllowLowerMemLevel = true;
4269                updateOomAdjLocked();
4270                doLowMemReportIfNeededLocked(null);
4271            }
4272        } finally {
4273            Binder.restoreCallingIdentity(callingId);
4274        }
4275    }
4276
4277    @Override
4278    public void forceStopPackage(final String packageName, int userId) {
4279        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4280                != PackageManager.PERMISSION_GRANTED) {
4281            String msg = "Permission Denial: forceStopPackage() from pid="
4282                    + Binder.getCallingPid()
4283                    + ", uid=" + Binder.getCallingUid()
4284                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4285            Slog.w(TAG, msg);
4286            throw new SecurityException(msg);
4287        }
4288        final int callingPid = Binder.getCallingPid();
4289        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4290                userId, true, true, "forceStopPackage", null);
4291        long callingId = Binder.clearCallingIdentity();
4292        try {
4293            IPackageManager pm = AppGlobals.getPackageManager();
4294            synchronized(this) {
4295                int[] users = userId == UserHandle.USER_ALL
4296                        ? getUsersLocked() : new int[] { userId };
4297                for (int user : users) {
4298                    int pkgUid = -1;
4299                    try {
4300                        pkgUid = pm.getPackageUid(packageName, user);
4301                    } catch (RemoteException e) {
4302                    }
4303                    if (pkgUid == -1) {
4304                        Slog.w(TAG, "Invalid packageName: " + packageName);
4305                        continue;
4306                    }
4307                    try {
4308                        pm.setPackageStoppedState(packageName, true, user);
4309                    } catch (RemoteException e) {
4310                    } catch (IllegalArgumentException e) {
4311                        Slog.w(TAG, "Failed trying to unstop package "
4312                                + packageName + ": " + e);
4313                    }
4314                    if (isUserRunningLocked(user, false)) {
4315                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4316                    }
4317                }
4318            }
4319        } finally {
4320            Binder.restoreCallingIdentity(callingId);
4321        }
4322    }
4323
4324    /*
4325     * The pkg name and app id have to be specified.
4326     */
4327    @Override
4328    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4329        if (pkg == null) {
4330            return;
4331        }
4332        // Make sure the uid is valid.
4333        if (appid < 0) {
4334            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4335            return;
4336        }
4337        int callerUid = Binder.getCallingUid();
4338        // Only the system server can kill an application
4339        if (callerUid == Process.SYSTEM_UID) {
4340            // Post an aysnc message to kill the application
4341            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4342            msg.arg1 = appid;
4343            msg.arg2 = 0;
4344            Bundle bundle = new Bundle();
4345            bundle.putString("pkg", pkg);
4346            bundle.putString("reason", reason);
4347            msg.obj = bundle;
4348            mHandler.sendMessage(msg);
4349        } else {
4350            throw new SecurityException(callerUid + " cannot kill pkg: " +
4351                    pkg);
4352        }
4353    }
4354
4355    @Override
4356    public void closeSystemDialogs(String reason) {
4357        enforceNotIsolatedCaller("closeSystemDialogs");
4358
4359        final int pid = Binder.getCallingPid();
4360        final int uid = Binder.getCallingUid();
4361        final long origId = Binder.clearCallingIdentity();
4362        try {
4363            synchronized (this) {
4364                // Only allow this from foreground processes, so that background
4365                // applications can't abuse it to prevent system UI from being shown.
4366                if (uid >= Process.FIRST_APPLICATION_UID) {
4367                    ProcessRecord proc;
4368                    synchronized (mPidsSelfLocked) {
4369                        proc = mPidsSelfLocked.get(pid);
4370                    }
4371                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4372                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4373                                + " from background process " + proc);
4374                        return;
4375                    }
4376                }
4377                closeSystemDialogsLocked(reason);
4378            }
4379        } finally {
4380            Binder.restoreCallingIdentity(origId);
4381        }
4382    }
4383
4384    void closeSystemDialogsLocked(String reason) {
4385        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4386        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4387                | Intent.FLAG_RECEIVER_FOREGROUND);
4388        if (reason != null) {
4389            intent.putExtra("reason", reason);
4390        }
4391        mWindowManager.closeSystemDialogs(reason);
4392
4393        mStackSupervisor.closeSystemDialogsLocked();
4394
4395        broadcastIntentLocked(null, null, intent, null,
4396                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4397                Process.SYSTEM_UID, UserHandle.USER_ALL);
4398    }
4399
4400    @Override
4401    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4402        enforceNotIsolatedCaller("getProcessMemoryInfo");
4403        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4404        for (int i=pids.length-1; i>=0; i--) {
4405            ProcessRecord proc;
4406            int oomAdj;
4407            synchronized (this) {
4408                synchronized (mPidsSelfLocked) {
4409                    proc = mPidsSelfLocked.get(pids[i]);
4410                    oomAdj = proc != null ? proc.setAdj : 0;
4411                }
4412            }
4413            infos[i] = new Debug.MemoryInfo();
4414            Debug.getMemoryInfo(pids[i], infos[i]);
4415            if (proc != null) {
4416                synchronized (this) {
4417                    if (proc.thread != null && proc.setAdj == oomAdj) {
4418                        // Record this for posterity if the process has been stable.
4419                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4420                                infos[i].getTotalUss(), false, proc.pkgList);
4421                    }
4422                }
4423            }
4424        }
4425        return infos;
4426    }
4427
4428    @Override
4429    public long[] getProcessPss(int[] pids) {
4430        enforceNotIsolatedCaller("getProcessPss");
4431        long[] pss = new long[pids.length];
4432        for (int i=pids.length-1; i>=0; i--) {
4433            ProcessRecord proc;
4434            int oomAdj;
4435            synchronized (this) {
4436                synchronized (mPidsSelfLocked) {
4437                    proc = mPidsSelfLocked.get(pids[i]);
4438                    oomAdj = proc != null ? proc.setAdj : 0;
4439                }
4440            }
4441            long[] tmpUss = new long[1];
4442            pss[i] = Debug.getPss(pids[i], tmpUss);
4443            if (proc != null) {
4444                synchronized (this) {
4445                    if (proc.thread != null && proc.setAdj == oomAdj) {
4446                        // Record this for posterity if the process has been stable.
4447                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4448                    }
4449                }
4450            }
4451        }
4452        return pss;
4453    }
4454
4455    @Override
4456    public void killApplicationProcess(String processName, int uid) {
4457        if (processName == null) {
4458            return;
4459        }
4460
4461        int callerUid = Binder.getCallingUid();
4462        // Only the system server can kill an application
4463        if (callerUid == Process.SYSTEM_UID) {
4464            synchronized (this) {
4465                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4466                if (app != null && app.thread != null) {
4467                    try {
4468                        app.thread.scheduleSuicide();
4469                    } catch (RemoteException e) {
4470                        // If the other end already died, then our work here is done.
4471                    }
4472                } else {
4473                    Slog.w(TAG, "Process/uid not found attempting kill of "
4474                            + processName + " / " + uid);
4475                }
4476            }
4477        } else {
4478            throw new SecurityException(callerUid + " cannot kill app process: " +
4479                    processName);
4480        }
4481    }
4482
4483    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4484        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4485                false, true, false, false, UserHandle.getUserId(uid), reason);
4486        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4487                Uri.fromParts("package", packageName, null));
4488        if (!mProcessesReady) {
4489            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4490                    | Intent.FLAG_RECEIVER_FOREGROUND);
4491        }
4492        intent.putExtra(Intent.EXTRA_UID, uid);
4493        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4494        broadcastIntentLocked(null, null, intent,
4495                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4496                false, false,
4497                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4498    }
4499
4500    private void forceStopUserLocked(int userId, String reason) {
4501        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4502        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4503        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4504                | Intent.FLAG_RECEIVER_FOREGROUND);
4505        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4506        broadcastIntentLocked(null, null, intent,
4507                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4508                false, false,
4509                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4510    }
4511
4512    private final boolean killPackageProcessesLocked(String packageName, int appId,
4513            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4514            boolean doit, boolean evenPersistent, String reason) {
4515        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4516
4517        // Remove all processes this package may have touched: all with the
4518        // same UID (except for the system or root user), and all whose name
4519        // matches the package name.
4520        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4521        final int NP = mProcessNames.getMap().size();
4522        for (int ip=0; ip<NP; ip++) {
4523            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4524            final int NA = apps.size();
4525            for (int ia=0; ia<NA; ia++) {
4526                ProcessRecord app = apps.valueAt(ia);
4527                if (app.persistent && !evenPersistent) {
4528                    // we don't kill persistent processes
4529                    continue;
4530                }
4531                if (app.removed) {
4532                    if (doit) {
4533                        procs.add(app);
4534                    }
4535                    continue;
4536                }
4537
4538                // Skip process if it doesn't meet our oom adj requirement.
4539                if (app.setAdj < minOomAdj) {
4540                    continue;
4541                }
4542
4543                // If no package is specified, we call all processes under the
4544                // give user id.
4545                if (packageName == null) {
4546                    if (app.userId != userId) {
4547                        continue;
4548                    }
4549                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4550                        continue;
4551                    }
4552                // Package has been specified, we want to hit all processes
4553                // that match it.  We need to qualify this by the processes
4554                // that are running under the specified app and user ID.
4555                } else {
4556                    if (UserHandle.getAppId(app.uid) != appId) {
4557                        continue;
4558                    }
4559                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4560                        continue;
4561                    }
4562                    if (!app.pkgList.containsKey(packageName)) {
4563                        continue;
4564                    }
4565                }
4566
4567                // Process has passed all conditions, kill it!
4568                if (!doit) {
4569                    return true;
4570                }
4571                app.removed = true;
4572                procs.add(app);
4573            }
4574        }
4575
4576        int N = procs.size();
4577        for (int i=0; i<N; i++) {
4578            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4579        }
4580        updateOomAdjLocked();
4581        return N > 0;
4582    }
4583
4584    private final boolean forceStopPackageLocked(String name, int appId,
4585            boolean callerWillRestart, boolean purgeCache, boolean doit,
4586            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4587        int i;
4588        int N;
4589
4590        if (userId == UserHandle.USER_ALL && name == null) {
4591            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4592        }
4593
4594        if (appId < 0 && name != null) {
4595            try {
4596                appId = UserHandle.getAppId(
4597                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4598            } catch (RemoteException e) {
4599            }
4600        }
4601
4602        if (doit) {
4603            if (name != null) {
4604                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4605                        + " user=" + userId + ": " + reason);
4606            } else {
4607                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4608            }
4609
4610            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4611            for (int ip=pmap.size()-1; ip>=0; ip--) {
4612                SparseArray<Long> ba = pmap.valueAt(ip);
4613                for (i=ba.size()-1; i>=0; i--) {
4614                    boolean remove = false;
4615                    final int entUid = ba.keyAt(i);
4616                    if (name != null) {
4617                        if (userId == UserHandle.USER_ALL) {
4618                            if (UserHandle.getAppId(entUid) == appId) {
4619                                remove = true;
4620                            }
4621                        } else {
4622                            if (entUid == UserHandle.getUid(userId, appId)) {
4623                                remove = true;
4624                            }
4625                        }
4626                    } else if (UserHandle.getUserId(entUid) == userId) {
4627                        remove = true;
4628                    }
4629                    if (remove) {
4630                        ba.removeAt(i);
4631                    }
4632                }
4633                if (ba.size() == 0) {
4634                    pmap.removeAt(ip);
4635                }
4636            }
4637        }
4638
4639        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4640                -100, callerWillRestart, true, doit, evenPersistent,
4641                name == null ? ("stop user " + userId) : ("stop " + name));
4642
4643        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4644            if (!doit) {
4645                return true;
4646            }
4647            didSomething = true;
4648        }
4649
4650        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4651            if (!doit) {
4652                return true;
4653            }
4654            didSomething = true;
4655        }
4656
4657        if (name == null) {
4658            // Remove all sticky broadcasts from this user.
4659            mStickyBroadcasts.remove(userId);
4660        }
4661
4662        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4663        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4664                userId, providers)) {
4665            if (!doit) {
4666                return true;
4667            }
4668            didSomething = true;
4669        }
4670        N = providers.size();
4671        for (i=0; i<N; i++) {
4672            removeDyingProviderLocked(null, providers.get(i), true);
4673        }
4674
4675        // Remove transient permissions granted from/to this package/user
4676        removeUriPermissionsForPackageLocked(name, userId, false);
4677
4678        if (name == null || uninstalling) {
4679            // Remove pending intents.  For now we only do this when force
4680            // stopping users, because we have some problems when doing this
4681            // for packages -- app widgets are not currently cleaned up for
4682            // such packages, so they can be left with bad pending intents.
4683            if (mIntentSenderRecords.size() > 0) {
4684                Iterator<WeakReference<PendingIntentRecord>> it
4685                        = mIntentSenderRecords.values().iterator();
4686                while (it.hasNext()) {
4687                    WeakReference<PendingIntentRecord> wpir = it.next();
4688                    if (wpir == null) {
4689                        it.remove();
4690                        continue;
4691                    }
4692                    PendingIntentRecord pir = wpir.get();
4693                    if (pir == null) {
4694                        it.remove();
4695                        continue;
4696                    }
4697                    if (name == null) {
4698                        // Stopping user, remove all objects for the user.
4699                        if (pir.key.userId != userId) {
4700                            // Not the same user, skip it.
4701                            continue;
4702                        }
4703                    } else {
4704                        if (UserHandle.getAppId(pir.uid) != appId) {
4705                            // Different app id, skip it.
4706                            continue;
4707                        }
4708                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4709                            // Different user, skip it.
4710                            continue;
4711                        }
4712                        if (!pir.key.packageName.equals(name)) {
4713                            // Different package, skip it.
4714                            continue;
4715                        }
4716                    }
4717                    if (!doit) {
4718                        return true;
4719                    }
4720                    didSomething = true;
4721                    it.remove();
4722                    pir.canceled = true;
4723                    if (pir.key.activity != null) {
4724                        pir.key.activity.pendingResults.remove(pir.ref);
4725                    }
4726                }
4727            }
4728        }
4729
4730        if (doit) {
4731            if (purgeCache && name != null) {
4732                AttributeCache ac = AttributeCache.instance();
4733                if (ac != null) {
4734                    ac.removePackage(name);
4735                }
4736            }
4737            if (mBooted) {
4738                mStackSupervisor.resumeTopActivitiesLocked();
4739                mStackSupervisor.scheduleIdleLocked();
4740            }
4741        }
4742
4743        return didSomething;
4744    }
4745
4746    private final boolean removeProcessLocked(ProcessRecord app,
4747            boolean callerWillRestart, boolean allowRestart, String reason) {
4748        final String name = app.processName;
4749        final int uid = app.uid;
4750        if (DEBUG_PROCESSES) Slog.d(
4751            TAG, "Force removing proc " + app.toShortString() + " (" + name
4752            + "/" + uid + ")");
4753
4754        mProcessNames.remove(name, uid);
4755        mIsolatedProcesses.remove(app.uid);
4756        if (mHeavyWeightProcess == app) {
4757            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4758                    mHeavyWeightProcess.userId, 0));
4759            mHeavyWeightProcess = null;
4760        }
4761        boolean needRestart = false;
4762        if (app.pid > 0 && app.pid != MY_PID) {
4763            int pid = app.pid;
4764            synchronized (mPidsSelfLocked) {
4765                mPidsSelfLocked.remove(pid);
4766                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4767            }
4768            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4769                    app.processName, app.info.uid);
4770            if (app.isolated) {
4771                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4772            }
4773            killUnneededProcessLocked(app, reason);
4774            handleAppDiedLocked(app, true, allowRestart);
4775            removeLruProcessLocked(app);
4776
4777            if (app.persistent && !app.isolated) {
4778                if (!callerWillRestart) {
4779                    addAppLocked(app.info, false);
4780                } else {
4781                    needRestart = true;
4782                }
4783            }
4784        } else {
4785            mRemovedProcesses.add(app);
4786        }
4787
4788        return needRestart;
4789    }
4790
4791    private final void processStartTimedOutLocked(ProcessRecord app) {
4792        final int pid = app.pid;
4793        boolean gone = false;
4794        synchronized (mPidsSelfLocked) {
4795            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4796            if (knownApp != null && knownApp.thread == null) {
4797                mPidsSelfLocked.remove(pid);
4798                gone = true;
4799            }
4800        }
4801
4802        if (gone) {
4803            Slog.w(TAG, "Process " + app + " failed to attach");
4804            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4805                    pid, app.uid, app.processName);
4806            mProcessNames.remove(app.processName, app.uid);
4807            mIsolatedProcesses.remove(app.uid);
4808            if (mHeavyWeightProcess == app) {
4809                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4810                        mHeavyWeightProcess.userId, 0));
4811                mHeavyWeightProcess = null;
4812            }
4813            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4814                    app.processName, app.info.uid);
4815            if (app.isolated) {
4816                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4817            }
4818            // Take care of any launching providers waiting for this process.
4819            checkAppInLaunchingProvidersLocked(app, true);
4820            // Take care of any services that are waiting for the process.
4821            mServices.processStartTimedOutLocked(app);
4822            killUnneededProcessLocked(app, "start timeout");
4823            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4824                Slog.w(TAG, "Unattached app died before backup, skipping");
4825                try {
4826                    IBackupManager bm = IBackupManager.Stub.asInterface(
4827                            ServiceManager.getService(Context.BACKUP_SERVICE));
4828                    bm.agentDisconnected(app.info.packageName);
4829                } catch (RemoteException e) {
4830                    // Can't happen; the backup manager is local
4831                }
4832            }
4833            if (isPendingBroadcastProcessLocked(pid)) {
4834                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4835                skipPendingBroadcastLocked(pid);
4836            }
4837        } else {
4838            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4839        }
4840    }
4841
4842    private final boolean attachApplicationLocked(IApplicationThread thread,
4843            int pid) {
4844
4845        // Find the application record that is being attached...  either via
4846        // the pid if we are running in multiple processes, or just pull the
4847        // next app record if we are emulating process with anonymous threads.
4848        ProcessRecord app;
4849        if (pid != MY_PID && pid >= 0) {
4850            synchronized (mPidsSelfLocked) {
4851                app = mPidsSelfLocked.get(pid);
4852            }
4853        } else {
4854            app = null;
4855        }
4856
4857        if (app == null) {
4858            Slog.w(TAG, "No pending application record for pid " + pid
4859                    + " (IApplicationThread " + thread + "); dropping process");
4860            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4861            if (pid > 0 && pid != MY_PID) {
4862                Process.killProcessQuiet(pid);
4863            } else {
4864                try {
4865                    thread.scheduleExit();
4866                } catch (Exception e) {
4867                    // Ignore exceptions.
4868                }
4869            }
4870            return false;
4871        }
4872
4873        // If this application record is still attached to a previous
4874        // process, clean it up now.
4875        if (app.thread != null) {
4876            handleAppDiedLocked(app, true, true);
4877        }
4878
4879        // Tell the process all about itself.
4880
4881        if (localLOGV) Slog.v(
4882                TAG, "Binding process pid " + pid + " to record " + app);
4883
4884        final String processName = app.processName;
4885        try {
4886            AppDeathRecipient adr = new AppDeathRecipient(
4887                    app, pid, thread);
4888            thread.asBinder().linkToDeath(adr, 0);
4889            app.deathRecipient = adr;
4890        } catch (RemoteException e) {
4891            app.resetPackageList(mProcessStats);
4892            startProcessLocked(app, "link fail", processName);
4893            return false;
4894        }
4895
4896        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4897
4898        app.makeActive(thread, mProcessStats);
4899        app.curAdj = app.setAdj = -100;
4900        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4901        app.forcingToForeground = null;
4902        updateProcessForegroundLocked(app, false, false);
4903        app.hasShownUi = false;
4904        app.debugging = false;
4905        app.cached = false;
4906
4907        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4908
4909        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4910        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4911
4912        if (!normalMode) {
4913            Slog.i(TAG, "Launching preboot mode app: " + app);
4914        }
4915
4916        if (localLOGV) Slog.v(
4917            TAG, "New app record " + app
4918            + " thread=" + thread.asBinder() + " pid=" + pid);
4919        try {
4920            int testMode = IApplicationThread.DEBUG_OFF;
4921            if (mDebugApp != null && mDebugApp.equals(processName)) {
4922                testMode = mWaitForDebugger
4923                    ? IApplicationThread.DEBUG_WAIT
4924                    : IApplicationThread.DEBUG_ON;
4925                app.debugging = true;
4926                if (mDebugTransient) {
4927                    mDebugApp = mOrigDebugApp;
4928                    mWaitForDebugger = mOrigWaitForDebugger;
4929                }
4930            }
4931            String profileFile = app.instrumentationProfileFile;
4932            ParcelFileDescriptor profileFd = null;
4933            boolean profileAutoStop = false;
4934            if (mProfileApp != null && mProfileApp.equals(processName)) {
4935                mProfileProc = app;
4936                profileFile = mProfileFile;
4937                profileFd = mProfileFd;
4938                profileAutoStop = mAutoStopProfiler;
4939            }
4940            boolean enableOpenGlTrace = false;
4941            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4942                enableOpenGlTrace = true;
4943                mOpenGlTraceApp = null;
4944            }
4945
4946            // If the app is being launched for restore or full backup, set it up specially
4947            boolean isRestrictedBackupMode = false;
4948            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4949                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4950                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4951                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4952            }
4953
4954            ensurePackageDexOpt(app.instrumentationInfo != null
4955                    ? app.instrumentationInfo.packageName
4956                    : app.info.packageName);
4957            if (app.instrumentationClass != null) {
4958                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4959            }
4960            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4961                    + processName + " with config " + mConfiguration);
4962            ApplicationInfo appInfo = app.instrumentationInfo != null
4963                    ? app.instrumentationInfo : app.info;
4964            app.compat = compatibilityInfoForPackageLocked(appInfo);
4965            if (profileFd != null) {
4966                profileFd = profileFd.dup();
4967            }
4968            thread.bindApplication(processName, appInfo, providers,
4969                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4970                    app.instrumentationArguments, app.instrumentationWatcher,
4971                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4972                    isRestrictedBackupMode || !normalMode, app.persistent,
4973                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4974                    mCoreSettingsObserver.getCoreSettingsLocked());
4975            updateLruProcessLocked(app, false, null);
4976            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4977        } catch (Exception e) {
4978            // todo: Yikes!  What should we do?  For now we will try to
4979            // start another process, but that could easily get us in
4980            // an infinite loop of restarting processes...
4981            Slog.w(TAG, "Exception thrown during bind!", e);
4982
4983            app.resetPackageList(mProcessStats);
4984            app.unlinkDeathRecipient();
4985            startProcessLocked(app, "bind fail", processName);
4986            return false;
4987        }
4988
4989        // Remove this record from the list of starting applications.
4990        mPersistentStartingProcesses.remove(app);
4991        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4992                "Attach application locked removing on hold: " + app);
4993        mProcessesOnHold.remove(app);
4994
4995        boolean badApp = false;
4996        boolean didSomething = false;
4997
4998        // See if the top visible activity is waiting to run in this process...
4999        if (normalMode) {
5000            try {
5001                if (mStackSupervisor.attachApplicationLocked(app)) {
5002                    didSomething = true;
5003                }
5004            } catch (Exception e) {
5005                badApp = true;
5006            }
5007        }
5008
5009        // Find any services that should be running in this process...
5010        if (!badApp) {
5011            try {
5012                didSomething |= mServices.attachApplicationLocked(app, processName);
5013            } catch (Exception e) {
5014                badApp = true;
5015            }
5016        }
5017
5018        // Check if a next-broadcast receiver is in this process...
5019        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5020            try {
5021                didSomething |= sendPendingBroadcastsLocked(app);
5022            } catch (Exception e) {
5023                // If the app died trying to launch the receiver we declare it 'bad'
5024                badApp = true;
5025            }
5026        }
5027
5028        // Check whether the next backup agent is in this process...
5029        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5030            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5031            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5032            try {
5033                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5034                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5035                        mBackupTarget.backupMode);
5036            } catch (Exception e) {
5037                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5038                e.printStackTrace();
5039            }
5040        }
5041
5042        if (badApp) {
5043            // todo: Also need to kill application to deal with all
5044            // kinds of exceptions.
5045            handleAppDiedLocked(app, false, true);
5046            return false;
5047        }
5048
5049        if (!didSomething) {
5050            updateOomAdjLocked();
5051        }
5052
5053        return true;
5054    }
5055
5056    @Override
5057    public final void attachApplication(IApplicationThread thread) {
5058        synchronized (this) {
5059            int callingPid = Binder.getCallingPid();
5060            final long origId = Binder.clearCallingIdentity();
5061            attachApplicationLocked(thread, callingPid);
5062            Binder.restoreCallingIdentity(origId);
5063        }
5064    }
5065
5066    @Override
5067    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5068        final long origId = Binder.clearCallingIdentity();
5069        synchronized (this) {
5070            ActivityStack stack = ActivityRecord.getStackLocked(token);
5071            if (stack != null) {
5072                ActivityRecord r =
5073                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5074                if (stopProfiling) {
5075                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5076                        try {
5077                            mProfileFd.close();
5078                        } catch (IOException e) {
5079                        }
5080                        clearProfilerLocked();
5081                    }
5082                }
5083            }
5084        }
5085        Binder.restoreCallingIdentity(origId);
5086    }
5087
5088    void enableScreenAfterBoot() {
5089        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5090                SystemClock.uptimeMillis());
5091        mWindowManager.enableScreenAfterBoot();
5092
5093        synchronized (this) {
5094            updateEventDispatchingLocked();
5095        }
5096    }
5097
5098    @Override
5099    public void showBootMessage(final CharSequence msg, final boolean always) {
5100        enforceNotIsolatedCaller("showBootMessage");
5101        mWindowManager.showBootMessage(msg, always);
5102    }
5103
5104    @Override
5105    public void dismissKeyguardOnNextActivity() {
5106        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5107        final long token = Binder.clearCallingIdentity();
5108        try {
5109            synchronized (this) {
5110                if (DEBUG_LOCKSCREEN) logLockScreen("");
5111                if (mLockScreenShown) {
5112                    mLockScreenShown = false;
5113                    comeOutOfSleepIfNeededLocked();
5114                }
5115                mStackSupervisor.setDismissKeyguard(true);
5116            }
5117        } finally {
5118            Binder.restoreCallingIdentity(token);
5119        }
5120    }
5121
5122    final void finishBooting() {
5123        IntentFilter pkgFilter = new IntentFilter();
5124        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5125        pkgFilter.addDataScheme("package");
5126        mContext.registerReceiver(new BroadcastReceiver() {
5127            @Override
5128            public void onReceive(Context context, Intent intent) {
5129                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5130                if (pkgs != null) {
5131                    for (String pkg : pkgs) {
5132                        synchronized (ActivityManagerService.this) {
5133                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5134                                    "finished booting")) {
5135                                setResultCode(Activity.RESULT_OK);
5136                                return;
5137                            }
5138                        }
5139                    }
5140                }
5141            }
5142        }, pkgFilter);
5143
5144        synchronized (this) {
5145            // Ensure that any processes we had put on hold are now started
5146            // up.
5147            final int NP = mProcessesOnHold.size();
5148            if (NP > 0) {
5149                ArrayList<ProcessRecord> procs =
5150                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5151                for (int ip=0; ip<NP; ip++) {
5152                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5153                            + procs.get(ip));
5154                    startProcessLocked(procs.get(ip), "on-hold", null);
5155                }
5156            }
5157
5158            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5159                // Start looking for apps that are abusing wake locks.
5160                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5161                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5162                // Tell anyone interested that we are done booting!
5163                SystemProperties.set("sys.boot_completed", "1");
5164                SystemProperties.set("dev.bootcomplete", "1");
5165                for (int i=0; i<mStartedUsers.size(); i++) {
5166                    UserStartedState uss = mStartedUsers.valueAt(i);
5167                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5168                        uss.mState = UserStartedState.STATE_RUNNING;
5169                        final int userId = mStartedUsers.keyAt(i);
5170                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5171                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5172                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5173                        broadcastIntentLocked(null, null, intent, null,
5174                                new IIntentReceiver.Stub() {
5175                                    @Override
5176                                    public void performReceive(Intent intent, int resultCode,
5177                                            String data, Bundle extras, boolean ordered,
5178                                            boolean sticky, int sendingUser) {
5179                                        synchronized (ActivityManagerService.this) {
5180                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5181                                                    true, false);
5182                                        }
5183                                    }
5184                                },
5185                                0, null, null,
5186                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5187                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5188                                userId);
5189                    }
5190                }
5191                scheduleStartRelatedUsersLocked();
5192            }
5193        }
5194    }
5195
5196    final void ensureBootCompleted() {
5197        boolean booting;
5198        boolean enableScreen;
5199        synchronized (this) {
5200            booting = mBooting;
5201            mBooting = false;
5202            enableScreen = !mBooted;
5203            mBooted = true;
5204        }
5205
5206        if (booting) {
5207            finishBooting();
5208        }
5209
5210        if (enableScreen) {
5211            enableScreenAfterBoot();
5212        }
5213    }
5214
5215    @Override
5216    public final void activityResumed(IBinder token) {
5217        final long origId = Binder.clearCallingIdentity();
5218        synchronized(this) {
5219            ActivityStack stack = ActivityRecord.getStackLocked(token);
5220            if (stack != null) {
5221                ActivityRecord.activityResumedLocked(token);
5222            }
5223        }
5224        Binder.restoreCallingIdentity(origId);
5225    }
5226
5227    @Override
5228    public final void activityPaused(IBinder token) {
5229        final long origId = Binder.clearCallingIdentity();
5230        synchronized(this) {
5231            ActivityStack stack = ActivityRecord.getStackLocked(token);
5232            if (stack != null) {
5233                stack.activityPausedLocked(token, false);
5234            }
5235        }
5236        Binder.restoreCallingIdentity(origId);
5237    }
5238
5239    @Override
5240    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5241            CharSequence description) {
5242        if (localLOGV) Slog.v(
5243            TAG, "Activity stopped: token=" + token);
5244
5245        // Refuse possible leaked file descriptors
5246        if (icicle != null && icicle.hasFileDescriptors()) {
5247            throw new IllegalArgumentException("File descriptors passed in Bundle");
5248        }
5249
5250        ActivityRecord r = null;
5251
5252        final long origId = Binder.clearCallingIdentity();
5253
5254        synchronized (this) {
5255            r = ActivityRecord.isInStackLocked(token);
5256            if (r != null) {
5257                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5258            }
5259        }
5260
5261        if (r != null) {
5262            sendPendingThumbnail(r, null, null, null, false);
5263        }
5264
5265        trimApplications();
5266
5267        Binder.restoreCallingIdentity(origId);
5268    }
5269
5270    @Override
5271    public final void activityDestroyed(IBinder token) {
5272        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5273        synchronized (this) {
5274            ActivityStack stack = ActivityRecord.getStackLocked(token);
5275            if (stack != null) {
5276                stack.activityDestroyedLocked(token);
5277            }
5278        }
5279    }
5280
5281    @Override
5282    public String getCallingPackage(IBinder token) {
5283        synchronized (this) {
5284            ActivityRecord r = getCallingRecordLocked(token);
5285            return r != null ? r.info.packageName : null;
5286        }
5287    }
5288
5289    @Override
5290    public ComponentName getCallingActivity(IBinder token) {
5291        synchronized (this) {
5292            ActivityRecord r = getCallingRecordLocked(token);
5293            return r != null ? r.intent.getComponent() : null;
5294        }
5295    }
5296
5297    private ActivityRecord getCallingRecordLocked(IBinder token) {
5298        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5299        if (r == null) {
5300            return null;
5301        }
5302        return r.resultTo;
5303    }
5304
5305    @Override
5306    public ComponentName getActivityClassForToken(IBinder token) {
5307        synchronized(this) {
5308            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5309            if (r == null) {
5310                return null;
5311            }
5312            return r.intent.getComponent();
5313        }
5314    }
5315
5316    @Override
5317    public String getPackageForToken(IBinder token) {
5318        synchronized(this) {
5319            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5320            if (r == null) {
5321                return null;
5322            }
5323            return r.packageName;
5324        }
5325    }
5326
5327    @Override
5328    public IIntentSender getIntentSender(int type,
5329            String packageName, IBinder token, String resultWho,
5330            int requestCode, Intent[] intents, String[] resolvedTypes,
5331            int flags, Bundle options, int userId) {
5332        enforceNotIsolatedCaller("getIntentSender");
5333        // Refuse possible leaked file descriptors
5334        if (intents != null) {
5335            if (intents.length < 1) {
5336                throw new IllegalArgumentException("Intents array length must be >= 1");
5337            }
5338            for (int i=0; i<intents.length; i++) {
5339                Intent intent = intents[i];
5340                if (intent != null) {
5341                    if (intent.hasFileDescriptors()) {
5342                        throw new IllegalArgumentException("File descriptors passed in Intent");
5343                    }
5344                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5345                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5346                        throw new IllegalArgumentException(
5347                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5348                    }
5349                    intents[i] = new Intent(intent);
5350                }
5351            }
5352            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5353                throw new IllegalArgumentException(
5354                        "Intent array length does not match resolvedTypes length");
5355            }
5356        }
5357        if (options != null) {
5358            if (options.hasFileDescriptors()) {
5359                throw new IllegalArgumentException("File descriptors passed in options");
5360            }
5361        }
5362
5363        synchronized(this) {
5364            int callingUid = Binder.getCallingUid();
5365            int origUserId = userId;
5366            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5367                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5368                    "getIntentSender", null);
5369            if (origUserId == UserHandle.USER_CURRENT) {
5370                // We don't want to evaluate this until the pending intent is
5371                // actually executed.  However, we do want to always do the
5372                // security checking for it above.
5373                userId = UserHandle.USER_CURRENT;
5374            }
5375            try {
5376                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5377                    int uid = AppGlobals.getPackageManager()
5378                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5379                    if (!UserHandle.isSameApp(callingUid, uid)) {
5380                        String msg = "Permission Denial: getIntentSender() from pid="
5381                            + Binder.getCallingPid()
5382                            + ", uid=" + Binder.getCallingUid()
5383                            + ", (need uid=" + uid + ")"
5384                            + " is not allowed to send as package " + packageName;
5385                        Slog.w(TAG, msg);
5386                        throw new SecurityException(msg);
5387                    }
5388                }
5389
5390                return getIntentSenderLocked(type, packageName, callingUid, userId,
5391                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5392
5393            } catch (RemoteException e) {
5394                throw new SecurityException(e);
5395            }
5396        }
5397    }
5398
5399    IIntentSender getIntentSenderLocked(int type, String packageName,
5400            int callingUid, int userId, IBinder token, String resultWho,
5401            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5402            Bundle options) {
5403        if (DEBUG_MU)
5404            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5405        ActivityRecord activity = null;
5406        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5407            activity = ActivityRecord.isInStackLocked(token);
5408            if (activity == null) {
5409                return null;
5410            }
5411            if (activity.finishing) {
5412                return null;
5413            }
5414        }
5415
5416        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5417        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5418        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5419        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5420                |PendingIntent.FLAG_UPDATE_CURRENT);
5421
5422        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5423                type, packageName, activity, resultWho,
5424                requestCode, intents, resolvedTypes, flags, options, userId);
5425        WeakReference<PendingIntentRecord> ref;
5426        ref = mIntentSenderRecords.get(key);
5427        PendingIntentRecord rec = ref != null ? ref.get() : null;
5428        if (rec != null) {
5429            if (!cancelCurrent) {
5430                if (updateCurrent) {
5431                    if (rec.key.requestIntent != null) {
5432                        rec.key.requestIntent.replaceExtras(intents != null ?
5433                                intents[intents.length - 1] : null);
5434                    }
5435                    if (intents != null) {
5436                        intents[intents.length-1] = rec.key.requestIntent;
5437                        rec.key.allIntents = intents;
5438                        rec.key.allResolvedTypes = resolvedTypes;
5439                    } else {
5440                        rec.key.allIntents = null;
5441                        rec.key.allResolvedTypes = null;
5442                    }
5443                }
5444                return rec;
5445            }
5446            rec.canceled = true;
5447            mIntentSenderRecords.remove(key);
5448        }
5449        if (noCreate) {
5450            return rec;
5451        }
5452        rec = new PendingIntentRecord(this, key, callingUid);
5453        mIntentSenderRecords.put(key, rec.ref);
5454        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5455            if (activity.pendingResults == null) {
5456                activity.pendingResults
5457                        = new HashSet<WeakReference<PendingIntentRecord>>();
5458            }
5459            activity.pendingResults.add(rec.ref);
5460        }
5461        return rec;
5462    }
5463
5464    @Override
5465    public void cancelIntentSender(IIntentSender sender) {
5466        if (!(sender instanceof PendingIntentRecord)) {
5467            return;
5468        }
5469        synchronized(this) {
5470            PendingIntentRecord rec = (PendingIntentRecord)sender;
5471            try {
5472                int uid = AppGlobals.getPackageManager()
5473                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5474                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5475                    String msg = "Permission Denial: cancelIntentSender() from pid="
5476                        + Binder.getCallingPid()
5477                        + ", uid=" + Binder.getCallingUid()
5478                        + " is not allowed to cancel packges "
5479                        + rec.key.packageName;
5480                    Slog.w(TAG, msg);
5481                    throw new SecurityException(msg);
5482                }
5483            } catch (RemoteException e) {
5484                throw new SecurityException(e);
5485            }
5486            cancelIntentSenderLocked(rec, true);
5487        }
5488    }
5489
5490    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5491        rec.canceled = true;
5492        mIntentSenderRecords.remove(rec.key);
5493        if (cleanActivity && rec.key.activity != null) {
5494            rec.key.activity.pendingResults.remove(rec.ref);
5495        }
5496    }
5497
5498    @Override
5499    public String getPackageForIntentSender(IIntentSender pendingResult) {
5500        if (!(pendingResult instanceof PendingIntentRecord)) {
5501            return null;
5502        }
5503        try {
5504            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5505            return res.key.packageName;
5506        } catch (ClassCastException e) {
5507        }
5508        return null;
5509    }
5510
5511    @Override
5512    public int getUidForIntentSender(IIntentSender sender) {
5513        if (sender instanceof PendingIntentRecord) {
5514            try {
5515                PendingIntentRecord res = (PendingIntentRecord)sender;
5516                return res.uid;
5517            } catch (ClassCastException e) {
5518            }
5519        }
5520        return -1;
5521    }
5522
5523    @Override
5524    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5525        if (!(pendingResult instanceof PendingIntentRecord)) {
5526            return false;
5527        }
5528        try {
5529            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5530            if (res.key.allIntents == null) {
5531                return false;
5532            }
5533            for (int i=0; i<res.key.allIntents.length; i++) {
5534                Intent intent = res.key.allIntents[i];
5535                if (intent.getPackage() != null && intent.getComponent() != null) {
5536                    return false;
5537                }
5538            }
5539            return true;
5540        } catch (ClassCastException e) {
5541        }
5542        return false;
5543    }
5544
5545    @Override
5546    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5547        if (!(pendingResult instanceof PendingIntentRecord)) {
5548            return false;
5549        }
5550        try {
5551            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5552            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5553                return true;
5554            }
5555            return false;
5556        } catch (ClassCastException e) {
5557        }
5558        return false;
5559    }
5560
5561    @Override
5562    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5563        if (!(pendingResult instanceof PendingIntentRecord)) {
5564            return null;
5565        }
5566        try {
5567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5568            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5569        } catch (ClassCastException e) {
5570        }
5571        return null;
5572    }
5573
5574    @Override
5575    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5576        if (!(pendingResult instanceof PendingIntentRecord)) {
5577            return null;
5578        }
5579        try {
5580            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5581            Intent intent = res.key.requestIntent;
5582            if (intent != null) {
5583                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5584                        || res.lastTagPrefix.equals(prefix))) {
5585                    return res.lastTag;
5586                }
5587                res.lastTagPrefix = prefix;
5588                StringBuilder sb = new StringBuilder(128);
5589                if (prefix != null) {
5590                    sb.append(prefix);
5591                }
5592                if (intent.getAction() != null) {
5593                    sb.append(intent.getAction());
5594                } else if (intent.getComponent() != null) {
5595                    intent.getComponent().appendShortString(sb);
5596                } else {
5597                    sb.append("?");
5598                }
5599                return res.lastTag = sb.toString();
5600            }
5601        } catch (ClassCastException e) {
5602        }
5603        return null;
5604    }
5605
5606    @Override
5607    public void setProcessLimit(int max) {
5608        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5609                "setProcessLimit()");
5610        synchronized (this) {
5611            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5612            mProcessLimitOverride = max;
5613        }
5614        trimApplications();
5615    }
5616
5617    @Override
5618    public int getProcessLimit() {
5619        synchronized (this) {
5620            return mProcessLimitOverride;
5621        }
5622    }
5623
5624    void foregroundTokenDied(ForegroundToken token) {
5625        synchronized (ActivityManagerService.this) {
5626            synchronized (mPidsSelfLocked) {
5627                ForegroundToken cur
5628                    = mForegroundProcesses.get(token.pid);
5629                if (cur != token) {
5630                    return;
5631                }
5632                mForegroundProcesses.remove(token.pid);
5633                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5634                if (pr == null) {
5635                    return;
5636                }
5637                pr.forcingToForeground = null;
5638                updateProcessForegroundLocked(pr, false, false);
5639            }
5640            updateOomAdjLocked();
5641        }
5642    }
5643
5644    @Override
5645    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5646        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5647                "setProcessForeground()");
5648        synchronized(this) {
5649            boolean changed = false;
5650
5651            synchronized (mPidsSelfLocked) {
5652                ProcessRecord pr = mPidsSelfLocked.get(pid);
5653                if (pr == null && isForeground) {
5654                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5655                    return;
5656                }
5657                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5658                if (oldToken != null) {
5659                    oldToken.token.unlinkToDeath(oldToken, 0);
5660                    mForegroundProcesses.remove(pid);
5661                    if (pr != null) {
5662                        pr.forcingToForeground = null;
5663                    }
5664                    changed = true;
5665                }
5666                if (isForeground && token != null) {
5667                    ForegroundToken newToken = new ForegroundToken() {
5668                        @Override
5669                        public void binderDied() {
5670                            foregroundTokenDied(this);
5671                        }
5672                    };
5673                    newToken.pid = pid;
5674                    newToken.token = token;
5675                    try {
5676                        token.linkToDeath(newToken, 0);
5677                        mForegroundProcesses.put(pid, newToken);
5678                        pr.forcingToForeground = token;
5679                        changed = true;
5680                    } catch (RemoteException e) {
5681                        // If the process died while doing this, we will later
5682                        // do the cleanup with the process death link.
5683                    }
5684                }
5685            }
5686
5687            if (changed) {
5688                updateOomAdjLocked();
5689            }
5690        }
5691    }
5692
5693    // =========================================================
5694    // PERMISSIONS
5695    // =========================================================
5696
5697    static class PermissionController extends IPermissionController.Stub {
5698        ActivityManagerService mActivityManagerService;
5699        PermissionController(ActivityManagerService activityManagerService) {
5700            mActivityManagerService = activityManagerService;
5701        }
5702
5703        @Override
5704        public boolean checkPermission(String permission, int pid, int uid) {
5705            return mActivityManagerService.checkPermission(permission, pid,
5706                    uid) == PackageManager.PERMISSION_GRANTED;
5707        }
5708    }
5709
5710    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5711        @Override
5712        public int checkComponentPermission(String permission, int pid, int uid,
5713                int owningUid, boolean exported) {
5714            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5715                    owningUid, exported);
5716        }
5717
5718        @Override
5719        public Object getAMSLock() {
5720            return ActivityManagerService.this;
5721        }
5722    }
5723
5724    /**
5725     * This can be called with or without the global lock held.
5726     */
5727    int checkComponentPermission(String permission, int pid, int uid,
5728            int owningUid, boolean exported) {
5729        // We might be performing an operation on behalf of an indirect binder
5730        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5731        // client identity accordingly before proceeding.
5732        Identity tlsIdentity = sCallerIdentity.get();
5733        if (tlsIdentity != null) {
5734            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5735                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5736            uid = tlsIdentity.uid;
5737            pid = tlsIdentity.pid;
5738        }
5739
5740        if (pid == MY_PID) {
5741            return PackageManager.PERMISSION_GRANTED;
5742        }
5743
5744        return ActivityManager.checkComponentPermission(permission, uid,
5745                owningUid, exported);
5746    }
5747
5748    /**
5749     * As the only public entry point for permissions checking, this method
5750     * can enforce the semantic that requesting a check on a null global
5751     * permission is automatically denied.  (Internally a null permission
5752     * string is used when calling {@link #checkComponentPermission} in cases
5753     * when only uid-based security is needed.)
5754     *
5755     * This can be called with or without the global lock held.
5756     */
5757    @Override
5758    public int checkPermission(String permission, int pid, int uid) {
5759        if (permission == null) {
5760            return PackageManager.PERMISSION_DENIED;
5761        }
5762        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5763    }
5764
5765    /**
5766     * Binder IPC calls go through the public entry point.
5767     * This can be called with or without the global lock held.
5768     */
5769    int checkCallingPermission(String permission) {
5770        return checkPermission(permission,
5771                Binder.getCallingPid(),
5772                UserHandle.getAppId(Binder.getCallingUid()));
5773    }
5774
5775    /**
5776     * This can be called with or without the global lock held.
5777     */
5778    void enforceCallingPermission(String permission, String func) {
5779        if (checkCallingPermission(permission)
5780                == PackageManager.PERMISSION_GRANTED) {
5781            return;
5782        }
5783
5784        String msg = "Permission Denial: " + func + " from pid="
5785                + Binder.getCallingPid()
5786                + ", uid=" + Binder.getCallingUid()
5787                + " requires " + permission;
5788        Slog.w(TAG, msg);
5789        throw new SecurityException(msg);
5790    }
5791
5792    /**
5793     * Determine if UID is holding permissions required to access {@link Uri} in
5794     * the given {@link ProviderInfo}. Final permission checking is always done
5795     * in {@link ContentProvider}.
5796     */
5797    private final boolean checkHoldingPermissionsLocked(
5798            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5799        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5800                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5801
5802        if (pi.applicationInfo.uid == uid) {
5803            return true;
5804        } else if (!pi.exported) {
5805            return false;
5806        }
5807
5808        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5809        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5810        try {
5811            // check if target holds top-level <provider> permissions
5812            if (!readMet && pi.readPermission != null
5813                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5814                readMet = true;
5815            }
5816            if (!writeMet && pi.writePermission != null
5817                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5818                writeMet = true;
5819            }
5820
5821            // track if unprotected read/write is allowed; any denied
5822            // <path-permission> below removes this ability
5823            boolean allowDefaultRead = pi.readPermission == null;
5824            boolean allowDefaultWrite = pi.writePermission == null;
5825
5826            // check if target holds any <path-permission> that match uri
5827            final PathPermission[] pps = pi.pathPermissions;
5828            if (pps != null) {
5829                final String path = uri.getPath();
5830                int i = pps.length;
5831                while (i > 0 && (!readMet || !writeMet)) {
5832                    i--;
5833                    PathPermission pp = pps[i];
5834                    if (pp.match(path)) {
5835                        if (!readMet) {
5836                            final String pprperm = pp.getReadPermission();
5837                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5838                                    + pprperm + " for " + pp.getPath()
5839                                    + ": match=" + pp.match(path)
5840                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5841                            if (pprperm != null) {
5842                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5843                                    readMet = true;
5844                                } else {
5845                                    allowDefaultRead = false;
5846                                }
5847                            }
5848                        }
5849                        if (!writeMet) {
5850                            final String ppwperm = pp.getWritePermission();
5851                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5852                                    + ppwperm + " for " + pp.getPath()
5853                                    + ": match=" + pp.match(path)
5854                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5855                            if (ppwperm != null) {
5856                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5857                                    writeMet = true;
5858                                } else {
5859                                    allowDefaultWrite = false;
5860                                }
5861                            }
5862                        }
5863                    }
5864                }
5865            }
5866
5867            // grant unprotected <provider> read/write, if not blocked by
5868            // <path-permission> above
5869            if (allowDefaultRead) readMet = true;
5870            if (allowDefaultWrite) writeMet = true;
5871
5872        } catch (RemoteException e) {
5873            return false;
5874        }
5875
5876        return readMet && writeMet;
5877    }
5878
5879    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5880        ProviderInfo pi = null;
5881        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5882        if (cpr != null) {
5883            pi = cpr.info;
5884        } else {
5885            try {
5886                pi = AppGlobals.getPackageManager().resolveContentProvider(
5887                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5888            } catch (RemoteException ex) {
5889            }
5890        }
5891        return pi;
5892    }
5893
5894    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5895        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5896        if (targetUris != null) {
5897            return targetUris.get(uri);
5898        } else {
5899            return null;
5900        }
5901    }
5902
5903    private UriPermission findOrCreateUriPermissionLocked(
5904            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5905        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5906        if (targetUris == null) {
5907            targetUris = Maps.newArrayMap();
5908            mGrantedUriPermissions.put(targetUid, targetUris);
5909        }
5910
5911        UriPermission perm = targetUris.get(uri);
5912        if (perm == null) {
5913            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5914            targetUris.put(uri, perm);
5915        }
5916
5917        return perm;
5918    }
5919
5920    private final boolean checkUriPermissionLocked(
5921            Uri uri, int uid, int modeFlags, int minStrength) {
5922        // Root gets to do everything.
5923        if (uid == 0) {
5924            return true;
5925        }
5926        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5927        if (perms == null) return false;
5928        UriPermission perm = perms.get(uri);
5929        if (perm == null) return false;
5930        return perm.getStrength(modeFlags) >= minStrength;
5931    }
5932
5933    @Override
5934    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5935        enforceNotIsolatedCaller("checkUriPermission");
5936
5937        // Another redirected-binder-call permissions check as in
5938        // {@link checkComponentPermission}.
5939        Identity tlsIdentity = sCallerIdentity.get();
5940        if (tlsIdentity != null) {
5941            uid = tlsIdentity.uid;
5942            pid = tlsIdentity.pid;
5943        }
5944
5945        // Our own process gets to do everything.
5946        if (pid == MY_PID) {
5947            return PackageManager.PERMISSION_GRANTED;
5948        }
5949        synchronized(this) {
5950            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5951                    ? PackageManager.PERMISSION_GRANTED
5952                    : PackageManager.PERMISSION_DENIED;
5953        }
5954    }
5955
5956    /**
5957     * Check if the targetPkg can be granted permission to access uri by
5958     * the callingUid using the given modeFlags.  Throws a security exception
5959     * if callingUid is not allowed to do this.  Returns the uid of the target
5960     * if the URI permission grant should be performed; returns -1 if it is not
5961     * needed (for example targetPkg already has permission to access the URI).
5962     * If you already know the uid of the target, you can supply it in
5963     * lastTargetUid else set that to -1.
5964     */
5965    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5966            Uri uri, int modeFlags, int lastTargetUid) {
5967        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5968        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5969                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5970        if (modeFlags == 0) {
5971            return -1;
5972        }
5973
5974        if (targetPkg != null) {
5975            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5976                    "Checking grant " + targetPkg + " permission to " + uri);
5977        }
5978
5979        final IPackageManager pm = AppGlobals.getPackageManager();
5980
5981        // If this is not a content: uri, we can't do anything with it.
5982        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5983            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5984                    "Can't grant URI permission for non-content URI: " + uri);
5985            return -1;
5986        }
5987
5988        final String authority = uri.getAuthority();
5989        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5990        if (pi == null) {
5991            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5992            return -1;
5993        }
5994
5995        int targetUid = lastTargetUid;
5996        if (targetUid < 0 && targetPkg != null) {
5997            try {
5998                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5999                if (targetUid < 0) {
6000                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6001                            "Can't grant URI permission no uid for: " + targetPkg);
6002                    return -1;
6003                }
6004            } catch (RemoteException ex) {
6005                return -1;
6006            }
6007        }
6008
6009        if (targetUid >= 0) {
6010            // First...  does the target actually need this permission?
6011            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6012                // No need to grant the target this permission.
6013                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6014                        "Target " + targetPkg + " already has full permission to " + uri);
6015                return -1;
6016            }
6017        } else {
6018            // First...  there is no target package, so can anyone access it?
6019            boolean allowed = pi.exported;
6020            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6021                if (pi.readPermission != null) {
6022                    allowed = false;
6023                }
6024            }
6025            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6026                if (pi.writePermission != null) {
6027                    allowed = false;
6028                }
6029            }
6030            if (allowed) {
6031                return -1;
6032            }
6033        }
6034
6035        // Second...  is the provider allowing granting of URI permissions?
6036        if (!pi.grantUriPermissions) {
6037            throw new SecurityException("Provider " + pi.packageName
6038                    + "/" + pi.name
6039                    + " does not allow granting of Uri permissions (uri "
6040                    + uri + ")");
6041        }
6042        if (pi.uriPermissionPatterns != null) {
6043            final int N = pi.uriPermissionPatterns.length;
6044            boolean allowed = false;
6045            for (int i=0; i<N; i++) {
6046                if (pi.uriPermissionPatterns[i] != null
6047                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6048                    allowed = true;
6049                    break;
6050                }
6051            }
6052            if (!allowed) {
6053                throw new SecurityException("Provider " + pi.packageName
6054                        + "/" + pi.name
6055                        + " does not allow granting of permission to path of Uri "
6056                        + uri);
6057            }
6058        }
6059
6060        // Third...  does the caller itself have permission to access
6061        // this uri?
6062        if (callingUid != Process.myUid()) {
6063            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6064                // Require they hold a strong enough Uri permission
6065                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6066                        : UriPermission.STRENGTH_OWNED;
6067                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6068                    throw new SecurityException("Uid " + callingUid
6069                            + " does not have permission to uri " + uri);
6070                }
6071            }
6072        }
6073
6074        return targetUid;
6075    }
6076
6077    @Override
6078    public int checkGrantUriPermission(int callingUid, String targetPkg,
6079            Uri uri, int modeFlags) {
6080        enforceNotIsolatedCaller("checkGrantUriPermission");
6081        synchronized(this) {
6082            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6083        }
6084    }
6085
6086    void grantUriPermissionUncheckedLocked(
6087            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6088        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6089        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6090                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6091        if (modeFlags == 0) {
6092            return;
6093        }
6094
6095        // So here we are: the caller has the assumed permission
6096        // to the uri, and the target doesn't.  Let's now give this to
6097        // the target.
6098
6099        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6100                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6101
6102        final String authority = uri.getAuthority();
6103        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6104        if (pi == null) {
6105            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6106            return;
6107        }
6108
6109        final UriPermission perm = findOrCreateUriPermissionLocked(
6110                pi.packageName, targetPkg, targetUid, uri);
6111        perm.grantModes(modeFlags, persistable, owner);
6112    }
6113
6114    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6115            int modeFlags, UriPermissionOwner owner) {
6116        if (targetPkg == null) {
6117            throw new NullPointerException("targetPkg");
6118        }
6119
6120        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6121        if (targetUid < 0) {
6122            return;
6123        }
6124
6125        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6126    }
6127
6128    static class NeededUriGrants extends ArrayList<Uri> {
6129        final String targetPkg;
6130        final int targetUid;
6131        final int flags;
6132
6133        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6134            this.targetPkg = targetPkg;
6135            this.targetUid = targetUid;
6136            this.flags = flags;
6137        }
6138    }
6139
6140    /**
6141     * Like checkGrantUriPermissionLocked, but takes an Intent.
6142     */
6143    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6144            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6145        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6146                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6147                + " clip=" + (intent != null ? intent.getClipData() : null)
6148                + " from " + intent + "; flags=0x"
6149                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6150
6151        if (targetPkg == null) {
6152            throw new NullPointerException("targetPkg");
6153        }
6154
6155        if (intent == null) {
6156            return null;
6157        }
6158        Uri data = intent.getData();
6159        ClipData clip = intent.getClipData();
6160        if (data == null && clip == null) {
6161            return null;
6162        }
6163
6164        if (data != null) {
6165            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6166                mode, needed != null ? needed.targetUid : -1);
6167            if (targetUid > 0) {
6168                if (needed == null) {
6169                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6170                }
6171                needed.add(data);
6172            }
6173        }
6174        if (clip != null) {
6175            for (int i=0; i<clip.getItemCount(); i++) {
6176                Uri uri = clip.getItemAt(i).getUri();
6177                if (uri != null) {
6178                    int targetUid = -1;
6179                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6180                            mode, needed != null ? needed.targetUid : -1);
6181                    if (targetUid > 0) {
6182                        if (needed == null) {
6183                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6184                        }
6185                        needed.add(uri);
6186                    }
6187                } else {
6188                    Intent clipIntent = clip.getItemAt(i).getIntent();
6189                    if (clipIntent != null) {
6190                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6191                                callingUid, targetPkg, clipIntent, mode, needed);
6192                        if (newNeeded != null) {
6193                            needed = newNeeded;
6194                        }
6195                    }
6196                }
6197            }
6198        }
6199
6200        return needed;
6201    }
6202
6203    /**
6204     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6205     */
6206    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6207            UriPermissionOwner owner) {
6208        if (needed != null) {
6209            for (int i=0; i<needed.size(); i++) {
6210                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6211                        needed.get(i), needed.flags, owner);
6212            }
6213        }
6214    }
6215
6216    void grantUriPermissionFromIntentLocked(int callingUid,
6217            String targetPkg, Intent intent, UriPermissionOwner owner) {
6218        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6219                intent, intent != null ? intent.getFlags() : 0, null);
6220        if (needed == null) {
6221            return;
6222        }
6223
6224        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6225    }
6226
6227    @Override
6228    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6229            Uri uri, int modeFlags) {
6230        enforceNotIsolatedCaller("grantUriPermission");
6231        synchronized(this) {
6232            final ProcessRecord r = getRecordForAppLocked(caller);
6233            if (r == null) {
6234                throw new SecurityException("Unable to find app for caller "
6235                        + caller
6236                        + " when granting permission to uri " + uri);
6237            }
6238            if (targetPkg == null) {
6239                throw new IllegalArgumentException("null target");
6240            }
6241            if (uri == null) {
6242                throw new IllegalArgumentException("null uri");
6243            }
6244
6245            // Persistable only supported through Intents
6246            Preconditions.checkFlagsArgument(modeFlags,
6247                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6248
6249            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6250                    null);
6251        }
6252    }
6253
6254    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6255        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6256                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6257            ArrayMap<Uri, UriPermission> perms
6258                    = mGrantedUriPermissions.get(perm.targetUid);
6259            if (perms != null) {
6260                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6261                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6262                perms.remove(perm.uri);
6263                if (perms.size() == 0) {
6264                    mGrantedUriPermissions.remove(perm.targetUid);
6265                }
6266            }
6267        }
6268    }
6269
6270    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6271        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6272
6273        final IPackageManager pm = AppGlobals.getPackageManager();
6274        final String authority = uri.getAuthority();
6275        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6276        if (pi == null) {
6277            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6278            return;
6279        }
6280
6281        // Does the caller have this permission on the URI?
6282        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6283            // Right now, if you are not the original owner of the permission,
6284            // you are not allowed to revoke it.
6285            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6286                throw new SecurityException("Uid " + callingUid
6287                        + " does not have permission to uri " + uri);
6288            //}
6289        }
6290
6291        boolean persistChanged = false;
6292
6293        // Go through all of the permissions and remove any that match.
6294        final List<String> SEGMENTS = uri.getPathSegments();
6295        if (SEGMENTS != null) {
6296            final int NS = SEGMENTS.size();
6297            int N = mGrantedUriPermissions.size();
6298            for (int i=0; i<N; i++) {
6299                ArrayMap<Uri, UriPermission> perms
6300                        = mGrantedUriPermissions.valueAt(i);
6301                Iterator<UriPermission> it = perms.values().iterator();
6302            toploop:
6303                while (it.hasNext()) {
6304                    UriPermission perm = it.next();
6305                    Uri targetUri = perm.uri;
6306                    if (!authority.equals(targetUri.getAuthority())) {
6307                        continue;
6308                    }
6309                    List<String> targetSegments = targetUri.getPathSegments();
6310                    if (targetSegments == null) {
6311                        continue;
6312                    }
6313                    if (targetSegments.size() < NS) {
6314                        continue;
6315                    }
6316                    for (int j=0; j<NS; j++) {
6317                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6318                            continue toploop;
6319                        }
6320                    }
6321                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6322                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6323                    persistChanged |= perm.clearModes(modeFlags, true);
6324                    if (perm.modeFlags == 0) {
6325                        it.remove();
6326                    }
6327                }
6328                if (perms.size() == 0) {
6329                    mGrantedUriPermissions.remove(
6330                            mGrantedUriPermissions.keyAt(i));
6331                    N--;
6332                    i--;
6333                }
6334            }
6335        }
6336
6337        if (persistChanged) {
6338            schedulePersistUriGrants();
6339        }
6340    }
6341
6342    @Override
6343    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6344            int modeFlags) {
6345        enforceNotIsolatedCaller("revokeUriPermission");
6346        synchronized(this) {
6347            final ProcessRecord r = getRecordForAppLocked(caller);
6348            if (r == null) {
6349                throw new SecurityException("Unable to find app for caller "
6350                        + caller
6351                        + " when revoking permission to uri " + uri);
6352            }
6353            if (uri == null) {
6354                Slog.w(TAG, "revokeUriPermission: null uri");
6355                return;
6356            }
6357
6358            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6359                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6360            if (modeFlags == 0) {
6361                return;
6362            }
6363
6364            final IPackageManager pm = AppGlobals.getPackageManager();
6365            final String authority = uri.getAuthority();
6366            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6367            if (pi == null) {
6368                Slog.w(TAG, "No content provider found for permission revoke: "
6369                        + uri.toSafeString());
6370                return;
6371            }
6372
6373            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6374        }
6375    }
6376
6377    /**
6378     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6379     * given package.
6380     *
6381     * @param packageName Package name to match, or {@code null} to apply to all
6382     *            packages.
6383     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6384     *            to all users.
6385     * @param persistable If persistable grants should be removed.
6386     */
6387    private void removeUriPermissionsForPackageLocked(
6388            String packageName, int userHandle, boolean persistable) {
6389        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6390            throw new IllegalArgumentException("Must narrow by either package or user");
6391        }
6392
6393        boolean persistChanged = false;
6394
6395        final int size = mGrantedUriPermissions.size();
6396        for (int i = 0; i < size; i++) {
6397            // Only inspect grants matching user
6398            if (userHandle == UserHandle.USER_ALL
6399                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6400                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6401                        .values().iterator();
6402                while (it.hasNext()) {
6403                    final UriPermission perm = it.next();
6404
6405                    // Only inspect grants matching package
6406                    if (packageName == null || perm.sourcePkg.equals(packageName)
6407                            || perm.targetPkg.equals(packageName)) {
6408                        persistChanged |= perm.clearModes(~0, persistable);
6409
6410                        // Only remove when no modes remain; any persisted grants
6411                        // will keep this alive.
6412                        if (perm.modeFlags == 0) {
6413                            it.remove();
6414                        }
6415                    }
6416                }
6417            }
6418        }
6419
6420        if (persistChanged) {
6421            schedulePersistUriGrants();
6422        }
6423    }
6424
6425    @Override
6426    public IBinder newUriPermissionOwner(String name) {
6427        enforceNotIsolatedCaller("newUriPermissionOwner");
6428        synchronized(this) {
6429            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6430            return owner.getExternalTokenLocked();
6431        }
6432    }
6433
6434    @Override
6435    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6436            Uri uri, int modeFlags) {
6437        synchronized(this) {
6438            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6439            if (owner == null) {
6440                throw new IllegalArgumentException("Unknown owner: " + token);
6441            }
6442            if (fromUid != Binder.getCallingUid()) {
6443                if (Binder.getCallingUid() != Process.myUid()) {
6444                    // Only system code can grant URI permissions on behalf
6445                    // of other users.
6446                    throw new SecurityException("nice try");
6447                }
6448            }
6449            if (targetPkg == null) {
6450                throw new IllegalArgumentException("null target");
6451            }
6452            if (uri == null) {
6453                throw new IllegalArgumentException("null uri");
6454            }
6455
6456            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6457        }
6458    }
6459
6460    @Override
6461    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6462        synchronized(this) {
6463            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6464            if (owner == null) {
6465                throw new IllegalArgumentException("Unknown owner: " + token);
6466            }
6467
6468            if (uri == null) {
6469                owner.removeUriPermissionsLocked(mode);
6470            } else {
6471                owner.removeUriPermissionLocked(uri, mode);
6472            }
6473        }
6474    }
6475
6476    private void schedulePersistUriGrants() {
6477        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6478            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6479                    10 * DateUtils.SECOND_IN_MILLIS);
6480        }
6481    }
6482
6483    private void writeGrantedUriPermissions() {
6484        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6485
6486        // Snapshot permissions so we can persist without lock
6487        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6488        synchronized (this) {
6489            final int size = mGrantedUriPermissions.size();
6490            for (int i = 0 ; i < size; i++) {
6491                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6492                    if (perm.persistedModeFlags != 0) {
6493                        persist.add(perm.snapshot());
6494                    }
6495                }
6496            }
6497        }
6498
6499        FileOutputStream fos = null;
6500        try {
6501            fos = mGrantFile.startWrite();
6502
6503            XmlSerializer out = new FastXmlSerializer();
6504            out.setOutput(fos, "utf-8");
6505            out.startDocument(null, true);
6506            out.startTag(null, TAG_URI_GRANTS);
6507            for (UriPermission.Snapshot perm : persist) {
6508                out.startTag(null, TAG_URI_GRANT);
6509                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6510                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6511                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6512                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6513                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6514                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6515                out.endTag(null, TAG_URI_GRANT);
6516            }
6517            out.endTag(null, TAG_URI_GRANTS);
6518            out.endDocument();
6519
6520            mGrantFile.finishWrite(fos);
6521        } catch (IOException e) {
6522            if (fos != null) {
6523                mGrantFile.failWrite(fos);
6524            }
6525        }
6526    }
6527
6528    private void readGrantedUriPermissionsLocked() {
6529        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6530
6531        final long now = System.currentTimeMillis();
6532
6533        FileInputStream fis = null;
6534        try {
6535            fis = mGrantFile.openRead();
6536            final XmlPullParser in = Xml.newPullParser();
6537            in.setInput(fis, null);
6538
6539            int type;
6540            while ((type = in.next()) != END_DOCUMENT) {
6541                final String tag = in.getName();
6542                if (type == START_TAG) {
6543                    if (TAG_URI_GRANT.equals(tag)) {
6544                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6545                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6546                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6547                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6548                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6549                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6550
6551                        // Sanity check that provider still belongs to source package
6552                        final ProviderInfo pi = getProviderInfoLocked(
6553                                uri.getAuthority(), userHandle);
6554                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6555                            int targetUid = -1;
6556                            try {
6557                                targetUid = AppGlobals.getPackageManager()
6558                                        .getPackageUid(targetPkg, userHandle);
6559                            } catch (RemoteException e) {
6560                            }
6561                            if (targetUid != -1) {
6562                                final UriPermission perm = findOrCreateUriPermissionLocked(
6563                                        sourcePkg, targetPkg, targetUid, uri);
6564                                perm.initPersistedModes(modeFlags, createdTime);
6565                            }
6566                        } else {
6567                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6568                                    + " but instead found " + pi);
6569                        }
6570                    }
6571                }
6572            }
6573        } catch (FileNotFoundException e) {
6574            // Missing grants is okay
6575        } catch (IOException e) {
6576            Log.wtf(TAG, "Failed reading Uri grants", e);
6577        } catch (XmlPullParserException e) {
6578            Log.wtf(TAG, "Failed reading Uri grants", e);
6579        } finally {
6580            IoUtils.closeQuietly(fis);
6581        }
6582    }
6583
6584    @Override
6585    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6586        enforceNotIsolatedCaller("takePersistableUriPermission");
6587
6588        Preconditions.checkFlagsArgument(modeFlags,
6589                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6590
6591        synchronized (this) {
6592            final int callingUid = Binder.getCallingUid();
6593            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6594            if (perm == null) {
6595                throw new SecurityException("No permission grant found for UID " + callingUid
6596                        + " and Uri " + uri.toSafeString());
6597            }
6598
6599            boolean persistChanged = perm.takePersistableModes(modeFlags);
6600            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6601
6602            if (persistChanged) {
6603                schedulePersistUriGrants();
6604            }
6605        }
6606    }
6607
6608    @Override
6609    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6610        enforceNotIsolatedCaller("releasePersistableUriPermission");
6611
6612        Preconditions.checkFlagsArgument(modeFlags,
6613                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6614
6615        synchronized (this) {
6616            final int callingUid = Binder.getCallingUid();
6617
6618            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6619            if (perm == null) {
6620                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6621                        + uri.toSafeString());
6622                return;
6623            }
6624
6625            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6626            removeUriPermissionIfNeededLocked(perm);
6627            if (persistChanged) {
6628                schedulePersistUriGrants();
6629            }
6630        }
6631    }
6632
6633    /**
6634     * Prune any older {@link UriPermission} for the given UID until outstanding
6635     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6636     *
6637     * @return if any mutations occured that require persisting.
6638     */
6639    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6640        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6641        if (perms == null) return false;
6642        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6643
6644        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6645        for (UriPermission perm : perms.values()) {
6646            if (perm.persistedModeFlags != 0) {
6647                persisted.add(perm);
6648            }
6649        }
6650
6651        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6652        if (trimCount <= 0) return false;
6653
6654        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6655        for (int i = 0; i < trimCount; i++) {
6656            final UriPermission perm = persisted.get(i);
6657
6658            if (DEBUG_URI_PERMISSION) {
6659                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6660            }
6661
6662            perm.releasePersistableModes(~0);
6663            removeUriPermissionIfNeededLocked(perm);
6664        }
6665
6666        return true;
6667    }
6668
6669    @Override
6670    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6671            String packageName, boolean incoming) {
6672        enforceNotIsolatedCaller("getPersistedUriPermissions");
6673        Preconditions.checkNotNull(packageName, "packageName");
6674
6675        final int callingUid = Binder.getCallingUid();
6676        final IPackageManager pm = AppGlobals.getPackageManager();
6677        try {
6678            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6679            if (packageUid != callingUid) {
6680                throw new SecurityException(
6681                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6682            }
6683        } catch (RemoteException e) {
6684            throw new SecurityException("Failed to verify package name ownership");
6685        }
6686
6687        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6688        synchronized (this) {
6689            if (incoming) {
6690                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6691                if (perms == null) {
6692                    Slog.w(TAG, "No permission grants found for " + packageName);
6693                } else {
6694                    final int size = perms.size();
6695                    for (int i = 0; i < size; i++) {
6696                        final UriPermission perm = perms.valueAt(i);
6697                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6698                            result.add(perm.buildPersistedPublicApiObject());
6699                        }
6700                    }
6701                }
6702            } else {
6703                final int size = mGrantedUriPermissions.size();
6704                for (int i = 0; i < size; i++) {
6705                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6706                    final int permsSize = perms.size();
6707                    for (int j = 0; j < permsSize; j++) {
6708                        final UriPermission perm = perms.valueAt(j);
6709                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6710                            result.add(perm.buildPersistedPublicApiObject());
6711                        }
6712                    }
6713                }
6714            }
6715        }
6716        return new ParceledListSlice<android.content.UriPermission>(result);
6717    }
6718
6719    @Override
6720    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6721        synchronized (this) {
6722            ProcessRecord app =
6723                who != null ? getRecordForAppLocked(who) : null;
6724            if (app == null) return;
6725
6726            Message msg = Message.obtain();
6727            msg.what = WAIT_FOR_DEBUGGER_MSG;
6728            msg.obj = app;
6729            msg.arg1 = waiting ? 1 : 0;
6730            mHandler.sendMessage(msg);
6731        }
6732    }
6733
6734    @Override
6735    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6736        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6737        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6738        outInfo.availMem = Process.getFreeMemory();
6739        outInfo.totalMem = Process.getTotalMemory();
6740        outInfo.threshold = homeAppMem;
6741        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6742        outInfo.hiddenAppThreshold = cachedAppMem;
6743        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6744                ProcessList.SERVICE_ADJ);
6745        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6746                ProcessList.VISIBLE_APP_ADJ);
6747        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6748                ProcessList.FOREGROUND_APP_ADJ);
6749    }
6750
6751    // =========================================================
6752    // TASK MANAGEMENT
6753    // =========================================================
6754
6755    @Override
6756    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6757                         IThumbnailReceiver receiver) {
6758        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6759
6760        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6761        ActivityRecord topRecord = null;
6762
6763        synchronized(this) {
6764            if (localLOGV) Slog.v(
6765                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6766                + ", receiver=" + receiver);
6767
6768            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6769                    != PackageManager.PERMISSION_GRANTED) {
6770                if (receiver != null) {
6771                    // If the caller wants to wait for pending thumbnails,
6772                    // it ain't gonna get them.
6773                    try {
6774                        receiver.finished();
6775                    } catch (RemoteException ex) {
6776                    }
6777                }
6778                String msg = "Permission Denial: getTasks() from pid="
6779                        + Binder.getCallingPid()
6780                        + ", uid=" + Binder.getCallingUid()
6781                        + " requires " + android.Manifest.permission.GET_TASKS;
6782                Slog.w(TAG, msg);
6783                throw new SecurityException(msg);
6784            }
6785
6786            // TODO: Improve with MRU list from all ActivityStacks.
6787            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6788
6789            if (!pending.pendingRecords.isEmpty()) {
6790                mPendingThumbnails.add(pending);
6791            }
6792        }
6793
6794        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6795
6796        if (topRecord != null) {
6797            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6798            try {
6799                IApplicationThread topThumbnail = topRecord.app.thread;
6800                topThumbnail.requestThumbnail(topRecord.appToken);
6801            } catch (Exception e) {
6802                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6803                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6804            }
6805        }
6806
6807        if (pending == null && receiver != null) {
6808            // In this case all thumbnails were available and the client
6809            // is being asked to be told when the remaining ones come in...
6810            // which is unusually, since the top-most currently running
6811            // activity should never have a canned thumbnail!  Oh well.
6812            try {
6813                receiver.finished();
6814            } catch (RemoteException ex) {
6815            }
6816        }
6817
6818        return list;
6819    }
6820
6821    TaskRecord getMostRecentTask() {
6822        return mRecentTasks.get(0);
6823    }
6824
6825    @Override
6826    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6827            int flags, int userId) {
6828        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6829                false, true, "getRecentTasks", null);
6830
6831        synchronized (this) {
6832            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6833                    "getRecentTasks()");
6834            final boolean detailed = checkCallingPermission(
6835                    android.Manifest.permission.GET_DETAILED_TASKS)
6836                    == PackageManager.PERMISSION_GRANTED;
6837
6838            IPackageManager pm = AppGlobals.getPackageManager();
6839
6840            final int N = mRecentTasks.size();
6841            ArrayList<ActivityManager.RecentTaskInfo> res
6842                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6843                            maxNum < N ? maxNum : N);
6844            for (int i=0; i<N && maxNum > 0; i++) {
6845                TaskRecord tr = mRecentTasks.get(i);
6846                // Only add calling user's recent tasks
6847                if (tr.userId != userId) continue;
6848                // Return the entry if desired by the caller.  We always return
6849                // the first entry, because callers always expect this to be the
6850                // foreground app.  We may filter others if the caller has
6851                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6852                // we should exclude the entry.
6853
6854                if (i == 0
6855                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6856                        || (tr.intent == null)
6857                        || ((tr.intent.getFlags()
6858                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6859                    ActivityManager.RecentTaskInfo rti
6860                            = new ActivityManager.RecentTaskInfo();
6861                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6862                    rti.persistentId = tr.taskId;
6863                    rti.baseIntent = new Intent(
6864                            tr.intent != null ? tr.intent : tr.affinityIntent);
6865                    if (!detailed) {
6866                        rti.baseIntent.replaceExtras((Bundle)null);
6867                    }
6868                    rti.origActivity = tr.origActivity;
6869                    rti.description = tr.lastDescription;
6870                    rti.stackId = tr.stack.mStackId;
6871
6872                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6873                        // Check whether this activity is currently available.
6874                        try {
6875                            if (rti.origActivity != null) {
6876                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6877                                        == null) {
6878                                    continue;
6879                                }
6880                            } else if (rti.baseIntent != null) {
6881                                if (pm.queryIntentActivities(rti.baseIntent,
6882                                        null, 0, userId) == null) {
6883                                    continue;
6884                                }
6885                            }
6886                        } catch (RemoteException e) {
6887                            // Will never happen.
6888                        }
6889                    }
6890
6891                    res.add(rti);
6892                    maxNum--;
6893                }
6894            }
6895            return res;
6896        }
6897    }
6898
6899    private TaskRecord recentTaskForIdLocked(int id) {
6900        final int N = mRecentTasks.size();
6901            for (int i=0; i<N; i++) {
6902                TaskRecord tr = mRecentTasks.get(i);
6903                if (tr.taskId == id) {
6904                    return tr;
6905                }
6906            }
6907            return null;
6908    }
6909
6910    @Override
6911    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6912        synchronized (this) {
6913            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6914                    "getTaskThumbnails()");
6915            TaskRecord tr = recentTaskForIdLocked(id);
6916            if (tr != null) {
6917                return tr.getTaskThumbnailsLocked();
6918            }
6919        }
6920        return null;
6921    }
6922
6923    @Override
6924    public Bitmap getTaskTopThumbnail(int id) {
6925        synchronized (this) {
6926            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6927                    "getTaskTopThumbnail()");
6928            TaskRecord tr = recentTaskForIdLocked(id);
6929            if (tr != null) {
6930                return tr.getTaskTopThumbnailLocked();
6931            }
6932        }
6933        return null;
6934    }
6935
6936    @Override
6937    public boolean removeSubTask(int taskId, int subTaskIndex) {
6938        synchronized (this) {
6939            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6940                    "removeSubTask()");
6941            long ident = Binder.clearCallingIdentity();
6942            try {
6943                TaskRecord tr = recentTaskForIdLocked(taskId);
6944                if (tr != null) {
6945                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6946                }
6947                return false;
6948            } finally {
6949                Binder.restoreCallingIdentity(ident);
6950            }
6951        }
6952    }
6953
6954    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6955        if (!pr.killedByAm) {
6956            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6957            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6958                    pr.processName, pr.setAdj, reason);
6959            pr.killedByAm = true;
6960            Process.killProcessQuiet(pr.pid);
6961        }
6962    }
6963
6964    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6965        tr.disposeThumbnail();
6966        mRecentTasks.remove(tr);
6967        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6968        Intent baseIntent = new Intent(
6969                tr.intent != null ? tr.intent : tr.affinityIntent);
6970        ComponentName component = baseIntent.getComponent();
6971        if (component == null) {
6972            Slog.w(TAG, "Now component for base intent of task: " + tr);
6973            return;
6974        }
6975
6976        // Find any running services associated with this app.
6977        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6978
6979        if (killProcesses) {
6980            // Find any running processes associated with this app.
6981            final String pkg = component.getPackageName();
6982            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6983            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6984            for (int i=0; i<pmap.size(); i++) {
6985                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6986                for (int j=0; j<uids.size(); j++) {
6987                    ProcessRecord proc = uids.valueAt(j);
6988                    if (proc.userId != tr.userId) {
6989                        continue;
6990                    }
6991                    if (!proc.pkgList.containsKey(pkg)) {
6992                        continue;
6993                    }
6994                    procs.add(proc);
6995                }
6996            }
6997
6998            // Kill the running processes.
6999            for (int i=0; i<procs.size(); i++) {
7000                ProcessRecord pr = procs.get(i);
7001                if (pr == mHomeProcess) {
7002                    // Don't kill the home process along with tasks from the same package.
7003                    continue;
7004                }
7005                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7006                    killUnneededProcessLocked(pr, "remove task");
7007                } else {
7008                    pr.waitingToKill = "remove task";
7009                }
7010            }
7011        }
7012    }
7013
7014    @Override
7015    public boolean removeTask(int taskId, int flags) {
7016        synchronized (this) {
7017            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7018                    "removeTask()");
7019            long ident = Binder.clearCallingIdentity();
7020            try {
7021                TaskRecord tr = recentTaskForIdLocked(taskId);
7022                if (tr != null) {
7023                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7024                    if (r != null) {
7025                        cleanUpRemovedTaskLocked(tr, flags);
7026                        return true;
7027                    }
7028                    if (tr.mActivities.size() == 0) {
7029                        // Caller is just removing a recent task that is
7030                        // not actively running.  That is easy!
7031                        cleanUpRemovedTaskLocked(tr, flags);
7032                        return true;
7033                    }
7034                    Slog.w(TAG, "removeTask: task " + taskId
7035                            + " does not have activities to remove, "
7036                            + " but numActivities=" + tr.numActivities
7037                            + ": " + tr);
7038                }
7039            } finally {
7040                Binder.restoreCallingIdentity(ident);
7041            }
7042        }
7043        return false;
7044    }
7045
7046    /**
7047     * TODO: Add mController hook
7048     */
7049    @Override
7050    public void moveTaskToFront(int task, int flags, Bundle options) {
7051        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7052                "moveTaskToFront()");
7053
7054        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7055        synchronized(this) {
7056            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7057                    Binder.getCallingUid(), "Task to front")) {
7058                ActivityOptions.abort(options);
7059                return;
7060            }
7061            final long origId = Binder.clearCallingIdentity();
7062            try {
7063                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7064            } finally {
7065                Binder.restoreCallingIdentity(origId);
7066            }
7067            ActivityOptions.abort(options);
7068        }
7069    }
7070
7071    @Override
7072    public void moveTaskToBack(int taskId) {
7073        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7074                "moveTaskToBack()");
7075
7076        synchronized(this) {
7077            TaskRecord tr = recentTaskForIdLocked(taskId);
7078            if (tr != null) {
7079                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7080                ActivityStack stack = tr.stack;
7081                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7082                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7083                            Binder.getCallingUid(), "Task to back")) {
7084                        return;
7085                    }
7086                }
7087                final long origId = Binder.clearCallingIdentity();
7088                try {
7089                    stack.moveTaskToBackLocked(taskId, null);
7090                } finally {
7091                    Binder.restoreCallingIdentity(origId);
7092                }
7093            }
7094        }
7095    }
7096
7097    /**
7098     * Moves an activity, and all of the other activities within the same task, to the bottom
7099     * of the history stack.  The activity's order within the task is unchanged.
7100     *
7101     * @param token A reference to the activity we wish to move
7102     * @param nonRoot If false then this only works if the activity is the root
7103     *                of a task; if true it will work for any activity in a task.
7104     * @return Returns true if the move completed, false if not.
7105     */
7106    @Override
7107    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7108        enforceNotIsolatedCaller("moveActivityTaskToBack");
7109        synchronized(this) {
7110            final long origId = Binder.clearCallingIdentity();
7111            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7112            if (taskId >= 0) {
7113                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7114            }
7115            Binder.restoreCallingIdentity(origId);
7116        }
7117        return false;
7118    }
7119
7120    @Override
7121    public void moveTaskBackwards(int task) {
7122        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7123                "moveTaskBackwards()");
7124
7125        synchronized(this) {
7126            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7127                    Binder.getCallingUid(), "Task backwards")) {
7128                return;
7129            }
7130            final long origId = Binder.clearCallingIdentity();
7131            moveTaskBackwardsLocked(task);
7132            Binder.restoreCallingIdentity(origId);
7133        }
7134    }
7135
7136    private final void moveTaskBackwardsLocked(int task) {
7137        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7138    }
7139
7140    @Override
7141    public IBinder getHomeActivityToken() throws RemoteException {
7142        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7143                "getHomeActivityToken()");
7144        synchronized (this) {
7145            return mStackSupervisor.getHomeActivityToken();
7146        }
7147    }
7148
7149    @Override
7150    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7151            IActivityContainerCallback callback) throws RemoteException {
7152        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7153                "createActivityContainer()");
7154        synchronized (this) {
7155            if (parentActivityToken == null) {
7156                throw new IllegalArgumentException("parent token must not be null");
7157            }
7158            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7159            if (r == null) {
7160                return null;
7161            }
7162            return mStackSupervisor.createActivityContainer(r, callback);
7163        }
7164    }
7165
7166    @Override
7167    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7168        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7169                "deleteActivityContainer()");
7170        synchronized (this) {
7171            mStackSupervisor.deleteActivityContainer(container);
7172        }
7173    }
7174
7175    @Override
7176    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7177            throws RemoteException {
7178        synchronized (this) {
7179            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7180            if (stack != null) {
7181                return stack.mActivityContainer;
7182            }
7183            return null;
7184        }
7185    }
7186
7187    @Override
7188    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7189        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7190                "moveTaskToStack()");
7191        if (stackId == HOME_STACK_ID) {
7192            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7193                    new RuntimeException("here").fillInStackTrace());
7194        }
7195        synchronized (this) {
7196            long ident = Binder.clearCallingIdentity();
7197            try {
7198                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7199                        + stackId + " toTop=" + toTop);
7200                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7201            } finally {
7202                Binder.restoreCallingIdentity(ident);
7203            }
7204        }
7205    }
7206
7207    @Override
7208    public void resizeStack(int stackBoxId, Rect bounds) {
7209        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7210                "resizeStackBox()");
7211        long ident = Binder.clearCallingIdentity();
7212        try {
7213            mWindowManager.resizeStack(stackBoxId, bounds);
7214        } finally {
7215            Binder.restoreCallingIdentity(ident);
7216        }
7217    }
7218
7219    @Override
7220    public List<StackInfo> getAllStackInfos() {
7221        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7222                "getAllStackInfos()");
7223        long ident = Binder.clearCallingIdentity();
7224        try {
7225            synchronized (this) {
7226                return mStackSupervisor.getAllStackInfosLocked();
7227            }
7228        } finally {
7229            Binder.restoreCallingIdentity(ident);
7230        }
7231    }
7232
7233    @Override
7234    public StackInfo getStackInfo(int stackId) {
7235        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7236                "getStackInfo()");
7237        long ident = Binder.clearCallingIdentity();
7238        try {
7239            synchronized (this) {
7240                return mStackSupervisor.getStackInfoLocked(stackId);
7241            }
7242        } finally {
7243            Binder.restoreCallingIdentity(ident);
7244        }
7245    }
7246
7247    @Override
7248    public boolean isInHomeStack(int taskId) {
7249        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7250                "getStackInfo()");
7251        long ident = Binder.clearCallingIdentity();
7252        try {
7253            synchronized (this) {
7254                TaskRecord tr = recentTaskForIdLocked(taskId);
7255                if (tr != null) {
7256                    return tr.stack.isHomeStack();
7257                }
7258            }
7259        } finally {
7260            Binder.restoreCallingIdentity(ident);
7261        }
7262        return false;
7263    }
7264
7265    @Override
7266    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7267        synchronized(this) {
7268            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7269        }
7270    }
7271
7272    // =========================================================
7273    // THUMBNAILS
7274    // =========================================================
7275
7276    public void reportThumbnail(IBinder token,
7277            Bitmap thumbnail, CharSequence description) {
7278        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7279        final long origId = Binder.clearCallingIdentity();
7280        sendPendingThumbnail(null, token, thumbnail, description, true);
7281        Binder.restoreCallingIdentity(origId);
7282    }
7283
7284    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7285            Bitmap thumbnail, CharSequence description, boolean always) {
7286        TaskRecord task;
7287        ArrayList<PendingThumbnailsRecord> receivers = null;
7288
7289        //System.out.println("Send pending thumbnail: " + r);
7290
7291        synchronized(this) {
7292            if (r == null) {
7293                r = ActivityRecord.isInStackLocked(token);
7294                if (r == null) {
7295                    return;
7296                }
7297            }
7298            if (thumbnail == null && r.thumbHolder != null) {
7299                thumbnail = r.thumbHolder.lastThumbnail;
7300                description = r.thumbHolder.lastDescription;
7301            }
7302            if (thumbnail == null && !always) {
7303                // If there is no thumbnail, and this entry is not actually
7304                // going away, then abort for now and pick up the next
7305                // thumbnail we get.
7306                return;
7307            }
7308            task = r.task;
7309
7310            int N = mPendingThumbnails.size();
7311            int i=0;
7312            while (i<N) {
7313                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7314                //System.out.println("Looking in " + pr.pendingRecords);
7315                if (pr.pendingRecords.remove(r)) {
7316                    if (receivers == null) {
7317                        receivers = new ArrayList<PendingThumbnailsRecord>();
7318                    }
7319                    receivers.add(pr);
7320                    if (pr.pendingRecords.size() == 0) {
7321                        pr.finished = true;
7322                        mPendingThumbnails.remove(i);
7323                        N--;
7324                        continue;
7325                    }
7326                }
7327                i++;
7328            }
7329        }
7330
7331        if (receivers != null) {
7332            final int N = receivers.size();
7333            for (int i=0; i<N; i++) {
7334                try {
7335                    PendingThumbnailsRecord pr = receivers.get(i);
7336                    pr.receiver.newThumbnail(
7337                        task != null ? task.taskId : -1, thumbnail, description);
7338                    if (pr.finished) {
7339                        pr.receiver.finished();
7340                    }
7341                } catch (Exception e) {
7342                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7343                }
7344            }
7345        }
7346    }
7347
7348    // =========================================================
7349    // CONTENT PROVIDERS
7350    // =========================================================
7351
7352    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7353        List<ProviderInfo> providers = null;
7354        try {
7355            providers = AppGlobals.getPackageManager().
7356                queryContentProviders(app.processName, app.uid,
7357                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7358        } catch (RemoteException ex) {
7359        }
7360        if (DEBUG_MU)
7361            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7362        int userId = app.userId;
7363        if (providers != null) {
7364            int N = providers.size();
7365            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7366            for (int i=0; i<N; i++) {
7367                ProviderInfo cpi =
7368                    (ProviderInfo)providers.get(i);
7369                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7370                        cpi.name, cpi.flags);
7371                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7372                    // This is a singleton provider, but a user besides the
7373                    // default user is asking to initialize a process it runs
7374                    // in...  well, no, it doesn't actually run in this process,
7375                    // it runs in the process of the default user.  Get rid of it.
7376                    providers.remove(i);
7377                    N--;
7378                    i--;
7379                    continue;
7380                }
7381
7382                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7383                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7384                if (cpr == null) {
7385                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7386                    mProviderMap.putProviderByClass(comp, cpr);
7387                }
7388                if (DEBUG_MU)
7389                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7390                app.pubProviders.put(cpi.name, cpr);
7391                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7392                    // Don't add this if it is a platform component that is marked
7393                    // to run in multiple processes, because this is actually
7394                    // part of the framework so doesn't make sense to track as a
7395                    // separate apk in the process.
7396                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7397                }
7398                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7399            }
7400        }
7401        return providers;
7402    }
7403
7404    /**
7405     * Check if {@link ProcessRecord} has a possible chance at accessing the
7406     * given {@link ProviderInfo}. Final permission checking is always done
7407     * in {@link ContentProvider}.
7408     */
7409    private final String checkContentProviderPermissionLocked(
7410            ProviderInfo cpi, ProcessRecord r) {
7411        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7412        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7413        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7414                cpi.applicationInfo.uid, cpi.exported)
7415                == PackageManager.PERMISSION_GRANTED) {
7416            return null;
7417        }
7418        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7419                cpi.applicationInfo.uid, cpi.exported)
7420                == PackageManager.PERMISSION_GRANTED) {
7421            return null;
7422        }
7423
7424        PathPermission[] pps = cpi.pathPermissions;
7425        if (pps != null) {
7426            int i = pps.length;
7427            while (i > 0) {
7428                i--;
7429                PathPermission pp = pps[i];
7430                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7431                        cpi.applicationInfo.uid, cpi.exported)
7432                        == PackageManager.PERMISSION_GRANTED) {
7433                    return null;
7434                }
7435                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7436                        cpi.applicationInfo.uid, cpi.exported)
7437                        == PackageManager.PERMISSION_GRANTED) {
7438                    return null;
7439                }
7440            }
7441        }
7442
7443        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7444        if (perms != null) {
7445            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7446                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7447                    return null;
7448                }
7449            }
7450        }
7451
7452        String msg;
7453        if (!cpi.exported) {
7454            msg = "Permission Denial: opening provider " + cpi.name
7455                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7456                    + ", uid=" + callingUid + ") that is not exported from uid "
7457                    + cpi.applicationInfo.uid;
7458        } else {
7459            msg = "Permission Denial: opening provider " + cpi.name
7460                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7461                    + ", uid=" + callingUid + ") requires "
7462                    + cpi.readPermission + " or " + cpi.writePermission;
7463        }
7464        Slog.w(TAG, msg);
7465        return msg;
7466    }
7467
7468    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7469            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7470        if (r != null) {
7471            for (int i=0; i<r.conProviders.size(); i++) {
7472                ContentProviderConnection conn = r.conProviders.get(i);
7473                if (conn.provider == cpr) {
7474                    if (DEBUG_PROVIDER) Slog.v(TAG,
7475                            "Adding provider requested by "
7476                            + r.processName + " from process "
7477                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7478                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7479                    if (stable) {
7480                        conn.stableCount++;
7481                        conn.numStableIncs++;
7482                    } else {
7483                        conn.unstableCount++;
7484                        conn.numUnstableIncs++;
7485                    }
7486                    return conn;
7487                }
7488            }
7489            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7490            if (stable) {
7491                conn.stableCount = 1;
7492                conn.numStableIncs = 1;
7493            } else {
7494                conn.unstableCount = 1;
7495                conn.numUnstableIncs = 1;
7496            }
7497            cpr.connections.add(conn);
7498            r.conProviders.add(conn);
7499            return conn;
7500        }
7501        cpr.addExternalProcessHandleLocked(externalProcessToken);
7502        return null;
7503    }
7504
7505    boolean decProviderCountLocked(ContentProviderConnection conn,
7506            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7507        if (conn != null) {
7508            cpr = conn.provider;
7509            if (DEBUG_PROVIDER) Slog.v(TAG,
7510                    "Removing provider requested by "
7511                    + conn.client.processName + " from process "
7512                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7513                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7514            if (stable) {
7515                conn.stableCount--;
7516            } else {
7517                conn.unstableCount--;
7518            }
7519            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7520                cpr.connections.remove(conn);
7521                conn.client.conProviders.remove(conn);
7522                return true;
7523            }
7524            return false;
7525        }
7526        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7527        return false;
7528    }
7529
7530    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7531            String name, IBinder token, boolean stable, int userId) {
7532        ContentProviderRecord cpr;
7533        ContentProviderConnection conn = null;
7534        ProviderInfo cpi = null;
7535
7536        synchronized(this) {
7537            ProcessRecord r = null;
7538            if (caller != null) {
7539                r = getRecordForAppLocked(caller);
7540                if (r == null) {
7541                    throw new SecurityException(
7542                            "Unable to find app for caller " + caller
7543                          + " (pid=" + Binder.getCallingPid()
7544                          + ") when getting content provider " + name);
7545                }
7546            }
7547
7548            // First check if this content provider has been published...
7549            cpr = mProviderMap.getProviderByName(name, userId);
7550            boolean providerRunning = cpr != null;
7551            if (providerRunning) {
7552                cpi = cpr.info;
7553                String msg;
7554                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7555                    throw new SecurityException(msg);
7556                }
7557
7558                if (r != null && cpr.canRunHere(r)) {
7559                    // This provider has been published or is in the process
7560                    // of being published...  but it is also allowed to run
7561                    // in the caller's process, so don't make a connection
7562                    // and just let the caller instantiate its own instance.
7563                    ContentProviderHolder holder = cpr.newHolder(null);
7564                    // don't give caller the provider object, it needs
7565                    // to make its own.
7566                    holder.provider = null;
7567                    return holder;
7568                }
7569
7570                final long origId = Binder.clearCallingIdentity();
7571
7572                // In this case the provider instance already exists, so we can
7573                // return it right away.
7574                conn = incProviderCountLocked(r, cpr, token, stable);
7575                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7576                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7577                        // If this is a perceptible app accessing the provider,
7578                        // make sure to count it as being accessed and thus
7579                        // back up on the LRU list.  This is good because
7580                        // content providers are often expensive to start.
7581                        updateLruProcessLocked(cpr.proc, false, null);
7582                    }
7583                }
7584
7585                if (cpr.proc != null) {
7586                    if (false) {
7587                        if (cpr.name.flattenToShortString().equals(
7588                                "com.android.providers.calendar/.CalendarProvider2")) {
7589                            Slog.v(TAG, "****************** KILLING "
7590                                + cpr.name.flattenToShortString());
7591                            Process.killProcess(cpr.proc.pid);
7592                        }
7593                    }
7594                    boolean success = updateOomAdjLocked(cpr.proc);
7595                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7596                    // NOTE: there is still a race here where a signal could be
7597                    // pending on the process even though we managed to update its
7598                    // adj level.  Not sure what to do about this, but at least
7599                    // the race is now smaller.
7600                    if (!success) {
7601                        // Uh oh...  it looks like the provider's process
7602                        // has been killed on us.  We need to wait for a new
7603                        // process to be started, and make sure its death
7604                        // doesn't kill our process.
7605                        Slog.i(TAG,
7606                                "Existing provider " + cpr.name.flattenToShortString()
7607                                + " is crashing; detaching " + r);
7608                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7609                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7610                        if (!lastRef) {
7611                            // This wasn't the last ref our process had on
7612                            // the provider...  we have now been killed, bail.
7613                            return null;
7614                        }
7615                        providerRunning = false;
7616                        conn = null;
7617                    }
7618                }
7619
7620                Binder.restoreCallingIdentity(origId);
7621            }
7622
7623            boolean singleton;
7624            if (!providerRunning) {
7625                try {
7626                    cpi = AppGlobals.getPackageManager().
7627                        resolveContentProvider(name,
7628                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7629                } catch (RemoteException ex) {
7630                }
7631                if (cpi == null) {
7632                    return null;
7633                }
7634                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7635                        cpi.name, cpi.flags);
7636                if (singleton) {
7637                    userId = 0;
7638                }
7639                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7640
7641                String msg;
7642                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7643                    throw new SecurityException(msg);
7644                }
7645
7646                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7647                        && !cpi.processName.equals("system")) {
7648                    // If this content provider does not run in the system
7649                    // process, and the system is not yet ready to run other
7650                    // processes, then fail fast instead of hanging.
7651                    throw new IllegalArgumentException(
7652                            "Attempt to launch content provider before system ready");
7653                }
7654
7655                // Make sure that the user who owns this provider is started.  If not,
7656                // we don't want to allow it to run.
7657                if (mStartedUsers.get(userId) == null) {
7658                    Slog.w(TAG, "Unable to launch app "
7659                            + cpi.applicationInfo.packageName + "/"
7660                            + cpi.applicationInfo.uid + " for provider "
7661                            + name + ": user " + userId + " is stopped");
7662                    return null;
7663                }
7664
7665                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7666                cpr = mProviderMap.getProviderByClass(comp, userId);
7667                final boolean firstClass = cpr == null;
7668                if (firstClass) {
7669                    try {
7670                        ApplicationInfo ai =
7671                            AppGlobals.getPackageManager().
7672                                getApplicationInfo(
7673                                        cpi.applicationInfo.packageName,
7674                                        STOCK_PM_FLAGS, userId);
7675                        if (ai == null) {
7676                            Slog.w(TAG, "No package info for content provider "
7677                                    + cpi.name);
7678                            return null;
7679                        }
7680                        ai = getAppInfoForUser(ai, userId);
7681                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7682                    } catch (RemoteException ex) {
7683                        // pm is in same process, this will never happen.
7684                    }
7685                }
7686
7687                if (r != null && cpr.canRunHere(r)) {
7688                    // If this is a multiprocess provider, then just return its
7689                    // info and allow the caller to instantiate it.  Only do
7690                    // this if the provider is the same user as the caller's
7691                    // process, or can run as root (so can be in any process).
7692                    return cpr.newHolder(null);
7693                }
7694
7695                if (DEBUG_PROVIDER) {
7696                    RuntimeException e = new RuntimeException("here");
7697                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7698                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7699                }
7700
7701                // This is single process, and our app is now connecting to it.
7702                // See if we are already in the process of launching this
7703                // provider.
7704                final int N = mLaunchingProviders.size();
7705                int i;
7706                for (i=0; i<N; i++) {
7707                    if (mLaunchingProviders.get(i) == cpr) {
7708                        break;
7709                    }
7710                }
7711
7712                // If the provider is not already being launched, then get it
7713                // started.
7714                if (i >= N) {
7715                    final long origId = Binder.clearCallingIdentity();
7716
7717                    try {
7718                        // Content provider is now in use, its package can't be stopped.
7719                        try {
7720                            AppGlobals.getPackageManager().setPackageStoppedState(
7721                                    cpr.appInfo.packageName, false, userId);
7722                        } catch (RemoteException e) {
7723                        } catch (IllegalArgumentException e) {
7724                            Slog.w(TAG, "Failed trying to unstop package "
7725                                    + cpr.appInfo.packageName + ": " + e);
7726                        }
7727
7728                        // Use existing process if already started
7729                        ProcessRecord proc = getProcessRecordLocked(
7730                                cpi.processName, cpr.appInfo.uid, false);
7731                        if (proc != null && proc.thread != null) {
7732                            if (DEBUG_PROVIDER) {
7733                                Slog.d(TAG, "Installing in existing process " + proc);
7734                            }
7735                            proc.pubProviders.put(cpi.name, cpr);
7736                            try {
7737                                proc.thread.scheduleInstallProvider(cpi);
7738                            } catch (RemoteException e) {
7739                            }
7740                        } else {
7741                            proc = startProcessLocked(cpi.processName,
7742                                    cpr.appInfo, false, 0, "content provider",
7743                                    new ComponentName(cpi.applicationInfo.packageName,
7744                                            cpi.name), false, false, false);
7745                            if (proc == null) {
7746                                Slog.w(TAG, "Unable to launch app "
7747                                        + cpi.applicationInfo.packageName + "/"
7748                                        + cpi.applicationInfo.uid + " for provider "
7749                                        + name + ": process is bad");
7750                                return null;
7751                            }
7752                        }
7753                        cpr.launchingApp = proc;
7754                        mLaunchingProviders.add(cpr);
7755                    } finally {
7756                        Binder.restoreCallingIdentity(origId);
7757                    }
7758                }
7759
7760                // Make sure the provider is published (the same provider class
7761                // may be published under multiple names).
7762                if (firstClass) {
7763                    mProviderMap.putProviderByClass(comp, cpr);
7764                }
7765
7766                mProviderMap.putProviderByName(name, cpr);
7767                conn = incProviderCountLocked(r, cpr, token, stable);
7768                if (conn != null) {
7769                    conn.waiting = true;
7770                }
7771            }
7772        }
7773
7774        // Wait for the provider to be published...
7775        synchronized (cpr) {
7776            while (cpr.provider == null) {
7777                if (cpr.launchingApp == null) {
7778                    Slog.w(TAG, "Unable to launch app "
7779                            + cpi.applicationInfo.packageName + "/"
7780                            + cpi.applicationInfo.uid + " for provider "
7781                            + name + ": launching app became null");
7782                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7783                            UserHandle.getUserId(cpi.applicationInfo.uid),
7784                            cpi.applicationInfo.packageName,
7785                            cpi.applicationInfo.uid, name);
7786                    return null;
7787                }
7788                try {
7789                    if (DEBUG_MU) {
7790                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7791                                + cpr.launchingApp);
7792                    }
7793                    if (conn != null) {
7794                        conn.waiting = true;
7795                    }
7796                    cpr.wait();
7797                } catch (InterruptedException ex) {
7798                } finally {
7799                    if (conn != null) {
7800                        conn.waiting = false;
7801                    }
7802                }
7803            }
7804        }
7805        return cpr != null ? cpr.newHolder(conn) : null;
7806    }
7807
7808    public final ContentProviderHolder getContentProvider(
7809            IApplicationThread caller, String name, int userId, boolean stable) {
7810        enforceNotIsolatedCaller("getContentProvider");
7811        if (caller == null) {
7812            String msg = "null IApplicationThread when getting content provider "
7813                    + name;
7814            Slog.w(TAG, msg);
7815            throw new SecurityException(msg);
7816        }
7817
7818        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7819                false, true, "getContentProvider", null);
7820        return getContentProviderImpl(caller, name, null, stable, userId);
7821    }
7822
7823    public ContentProviderHolder getContentProviderExternal(
7824            String name, int userId, IBinder token) {
7825        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7826            "Do not have permission in call getContentProviderExternal()");
7827        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7828                false, true, "getContentProvider", null);
7829        return getContentProviderExternalUnchecked(name, token, userId);
7830    }
7831
7832    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7833            IBinder token, int userId) {
7834        return getContentProviderImpl(null, name, token, true, userId);
7835    }
7836
7837    /**
7838     * Drop a content provider from a ProcessRecord's bookkeeping
7839     */
7840    public void removeContentProvider(IBinder connection, boolean stable) {
7841        enforceNotIsolatedCaller("removeContentProvider");
7842        long ident = Binder.clearCallingIdentity();
7843        try {
7844            synchronized (this) {
7845                ContentProviderConnection conn;
7846                try {
7847                    conn = (ContentProviderConnection)connection;
7848                } catch (ClassCastException e) {
7849                    String msg ="removeContentProvider: " + connection
7850                            + " not a ContentProviderConnection";
7851                    Slog.w(TAG, msg);
7852                    throw new IllegalArgumentException(msg);
7853                }
7854                if (conn == null) {
7855                    throw new NullPointerException("connection is null");
7856                }
7857                if (decProviderCountLocked(conn, null, null, stable)) {
7858                    updateOomAdjLocked();
7859                }
7860            }
7861        } finally {
7862            Binder.restoreCallingIdentity(ident);
7863        }
7864    }
7865
7866    public void removeContentProviderExternal(String name, IBinder token) {
7867        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7868            "Do not have permission in call removeContentProviderExternal()");
7869        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7870    }
7871
7872    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7873        synchronized (this) {
7874            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7875            if(cpr == null) {
7876                //remove from mProvidersByClass
7877                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7878                return;
7879            }
7880
7881            //update content provider record entry info
7882            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7883            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7884            if (localCpr.hasExternalProcessHandles()) {
7885                if (localCpr.removeExternalProcessHandleLocked(token)) {
7886                    updateOomAdjLocked();
7887                } else {
7888                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7889                            + " with no external reference for token: "
7890                            + token + ".");
7891                }
7892            } else {
7893                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7894                        + " with no external references.");
7895            }
7896        }
7897    }
7898
7899    public final void publishContentProviders(IApplicationThread caller,
7900            List<ContentProviderHolder> providers) {
7901        if (providers == null) {
7902            return;
7903        }
7904
7905        enforceNotIsolatedCaller("publishContentProviders");
7906        synchronized (this) {
7907            final ProcessRecord r = getRecordForAppLocked(caller);
7908            if (DEBUG_MU)
7909                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7910            if (r == null) {
7911                throw new SecurityException(
7912                        "Unable to find app for caller " + caller
7913                      + " (pid=" + Binder.getCallingPid()
7914                      + ") when publishing content providers");
7915            }
7916
7917            final long origId = Binder.clearCallingIdentity();
7918
7919            final int N = providers.size();
7920            for (int i=0; i<N; i++) {
7921                ContentProviderHolder src = providers.get(i);
7922                if (src == null || src.info == null || src.provider == null) {
7923                    continue;
7924                }
7925                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7926                if (DEBUG_MU)
7927                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7928                if (dst != null) {
7929                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7930                    mProviderMap.putProviderByClass(comp, dst);
7931                    String names[] = dst.info.authority.split(";");
7932                    for (int j = 0; j < names.length; j++) {
7933                        mProviderMap.putProviderByName(names[j], dst);
7934                    }
7935
7936                    int NL = mLaunchingProviders.size();
7937                    int j;
7938                    for (j=0; j<NL; j++) {
7939                        if (mLaunchingProviders.get(j) == dst) {
7940                            mLaunchingProviders.remove(j);
7941                            j--;
7942                            NL--;
7943                        }
7944                    }
7945                    synchronized (dst) {
7946                        dst.provider = src.provider;
7947                        dst.proc = r;
7948                        dst.notifyAll();
7949                    }
7950                    updateOomAdjLocked(r);
7951                }
7952            }
7953
7954            Binder.restoreCallingIdentity(origId);
7955        }
7956    }
7957
7958    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7959        ContentProviderConnection conn;
7960        try {
7961            conn = (ContentProviderConnection)connection;
7962        } catch (ClassCastException e) {
7963            String msg ="refContentProvider: " + connection
7964                    + " not a ContentProviderConnection";
7965            Slog.w(TAG, msg);
7966            throw new IllegalArgumentException(msg);
7967        }
7968        if (conn == null) {
7969            throw new NullPointerException("connection is null");
7970        }
7971
7972        synchronized (this) {
7973            if (stable > 0) {
7974                conn.numStableIncs += stable;
7975            }
7976            stable = conn.stableCount + stable;
7977            if (stable < 0) {
7978                throw new IllegalStateException("stableCount < 0: " + stable);
7979            }
7980
7981            if (unstable > 0) {
7982                conn.numUnstableIncs += unstable;
7983            }
7984            unstable = conn.unstableCount + unstable;
7985            if (unstable < 0) {
7986                throw new IllegalStateException("unstableCount < 0: " + unstable);
7987            }
7988
7989            if ((stable+unstable) <= 0) {
7990                throw new IllegalStateException("ref counts can't go to zero here: stable="
7991                        + stable + " unstable=" + unstable);
7992            }
7993            conn.stableCount = stable;
7994            conn.unstableCount = unstable;
7995            return !conn.dead;
7996        }
7997    }
7998
7999    public void unstableProviderDied(IBinder connection) {
8000        ContentProviderConnection conn;
8001        try {
8002            conn = (ContentProviderConnection)connection;
8003        } catch (ClassCastException e) {
8004            String msg ="refContentProvider: " + connection
8005                    + " not a ContentProviderConnection";
8006            Slog.w(TAG, msg);
8007            throw new IllegalArgumentException(msg);
8008        }
8009        if (conn == null) {
8010            throw new NullPointerException("connection is null");
8011        }
8012
8013        // Safely retrieve the content provider associated with the connection.
8014        IContentProvider provider;
8015        synchronized (this) {
8016            provider = conn.provider.provider;
8017        }
8018
8019        if (provider == null) {
8020            // Um, yeah, we're way ahead of you.
8021            return;
8022        }
8023
8024        // Make sure the caller is being honest with us.
8025        if (provider.asBinder().pingBinder()) {
8026            // Er, no, still looks good to us.
8027            synchronized (this) {
8028                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8029                        + " says " + conn + " died, but we don't agree");
8030                return;
8031            }
8032        }
8033
8034        // Well look at that!  It's dead!
8035        synchronized (this) {
8036            if (conn.provider.provider != provider) {
8037                // But something changed...  good enough.
8038                return;
8039            }
8040
8041            ProcessRecord proc = conn.provider.proc;
8042            if (proc == null || proc.thread == null) {
8043                // Seems like the process is already cleaned up.
8044                return;
8045            }
8046
8047            // As far as we're concerned, this is just like receiving a
8048            // death notification...  just a bit prematurely.
8049            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8050                    + ") early provider death");
8051            final long ident = Binder.clearCallingIdentity();
8052            try {
8053                appDiedLocked(proc, proc.pid, proc.thread);
8054            } finally {
8055                Binder.restoreCallingIdentity(ident);
8056            }
8057        }
8058    }
8059
8060    @Override
8061    public void appNotRespondingViaProvider(IBinder connection) {
8062        enforceCallingPermission(
8063                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8064
8065        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8066        if (conn == null) {
8067            Slog.w(TAG, "ContentProviderConnection is null");
8068            return;
8069        }
8070
8071        final ProcessRecord host = conn.provider.proc;
8072        if (host == null) {
8073            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8074            return;
8075        }
8076
8077        final long token = Binder.clearCallingIdentity();
8078        try {
8079            appNotResponding(host, null, null, false, "ContentProvider not responding");
8080        } finally {
8081            Binder.restoreCallingIdentity(token);
8082        }
8083    }
8084
8085    public final void installSystemProviders() {
8086        List<ProviderInfo> providers;
8087        synchronized (this) {
8088            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8089            providers = generateApplicationProvidersLocked(app);
8090            if (providers != null) {
8091                for (int i=providers.size()-1; i>=0; i--) {
8092                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8093                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8094                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8095                                + ": not system .apk");
8096                        providers.remove(i);
8097                    }
8098                }
8099            }
8100        }
8101        if (providers != null) {
8102            mSystemThread.installSystemProviders(providers);
8103        }
8104
8105        mCoreSettingsObserver = new CoreSettingsObserver(this);
8106
8107        mUsageStatsService.monitorPackages();
8108    }
8109
8110    /**
8111     * Allows app to retrieve the MIME type of a URI without having permission
8112     * to access its content provider.
8113     *
8114     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8115     *
8116     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8117     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8118     */
8119    public String getProviderMimeType(Uri uri, int userId) {
8120        enforceNotIsolatedCaller("getProviderMimeType");
8121        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8122                userId, false, true, "getProviderMimeType", null);
8123        final String name = uri.getAuthority();
8124        final long ident = Binder.clearCallingIdentity();
8125        ContentProviderHolder holder = null;
8126
8127        try {
8128            holder = getContentProviderExternalUnchecked(name, null, userId);
8129            if (holder != null) {
8130                return holder.provider.getType(uri);
8131            }
8132        } catch (RemoteException e) {
8133            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8134            return null;
8135        } finally {
8136            if (holder != null) {
8137                removeContentProviderExternalUnchecked(name, null, userId);
8138            }
8139            Binder.restoreCallingIdentity(ident);
8140        }
8141
8142        return null;
8143    }
8144
8145    // =========================================================
8146    // GLOBAL MANAGEMENT
8147    // =========================================================
8148
8149    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8150            boolean isolated) {
8151        String proc = customProcess != null ? customProcess : info.processName;
8152        BatteryStatsImpl.Uid.Proc ps = null;
8153        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8154        int uid = info.uid;
8155        if (isolated) {
8156            int userId = UserHandle.getUserId(uid);
8157            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8158            while (true) {
8159                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8160                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8161                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8162                }
8163                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8164                mNextIsolatedProcessUid++;
8165                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8166                    // No process for this uid, use it.
8167                    break;
8168                }
8169                stepsLeft--;
8170                if (stepsLeft <= 0) {
8171                    return null;
8172                }
8173            }
8174        }
8175        return new ProcessRecord(stats, info, proc, uid);
8176    }
8177
8178    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8179        ProcessRecord app;
8180        if (!isolated) {
8181            app = getProcessRecordLocked(info.processName, info.uid, true);
8182        } else {
8183            app = null;
8184        }
8185
8186        if (app == null) {
8187            app = newProcessRecordLocked(info, null, isolated);
8188            mProcessNames.put(info.processName, app.uid, app);
8189            if (isolated) {
8190                mIsolatedProcesses.put(app.uid, app);
8191            }
8192            updateLruProcessLocked(app, false, null);
8193            updateOomAdjLocked();
8194        }
8195
8196        // This package really, really can not be stopped.
8197        try {
8198            AppGlobals.getPackageManager().setPackageStoppedState(
8199                    info.packageName, false, UserHandle.getUserId(app.uid));
8200        } catch (RemoteException e) {
8201        } catch (IllegalArgumentException e) {
8202            Slog.w(TAG, "Failed trying to unstop package "
8203                    + info.packageName + ": " + e);
8204        }
8205
8206        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8207                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8208            app.persistent = true;
8209            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8210        }
8211        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8212            mPersistentStartingProcesses.add(app);
8213            startProcessLocked(app, "added application", app.processName);
8214        }
8215
8216        return app;
8217    }
8218
8219    public void unhandledBack() {
8220        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8221                "unhandledBack()");
8222
8223        synchronized(this) {
8224            final long origId = Binder.clearCallingIdentity();
8225            try {
8226                getFocusedStack().unhandledBackLocked();
8227            } finally {
8228                Binder.restoreCallingIdentity(origId);
8229            }
8230        }
8231    }
8232
8233    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8234        enforceNotIsolatedCaller("openContentUri");
8235        final int userId = UserHandle.getCallingUserId();
8236        String name = uri.getAuthority();
8237        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8238        ParcelFileDescriptor pfd = null;
8239        if (cph != null) {
8240            // We record the binder invoker's uid in thread-local storage before
8241            // going to the content provider to open the file.  Later, in the code
8242            // that handles all permissions checks, we look for this uid and use
8243            // that rather than the Activity Manager's own uid.  The effect is that
8244            // we do the check against the caller's permissions even though it looks
8245            // to the content provider like the Activity Manager itself is making
8246            // the request.
8247            sCallerIdentity.set(new Identity(
8248                    Binder.getCallingPid(), Binder.getCallingUid()));
8249            try {
8250                pfd = cph.provider.openFile(null, uri, "r", null);
8251            } catch (FileNotFoundException e) {
8252                // do nothing; pfd will be returned null
8253            } finally {
8254                // Ensure that whatever happens, we clean up the identity state
8255                sCallerIdentity.remove();
8256            }
8257
8258            // We've got the fd now, so we're done with the provider.
8259            removeContentProviderExternalUnchecked(name, null, userId);
8260        } else {
8261            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8262        }
8263        return pfd;
8264    }
8265
8266    // Actually is sleeping or shutting down or whatever else in the future
8267    // is an inactive state.
8268    public boolean isSleepingOrShuttingDown() {
8269        return mSleeping || mShuttingDown;
8270    }
8271
8272    public void goingToSleep() {
8273        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8274                != PackageManager.PERMISSION_GRANTED) {
8275            throw new SecurityException("Requires permission "
8276                    + android.Manifest.permission.DEVICE_POWER);
8277        }
8278
8279        synchronized(this) {
8280            mWentToSleep = true;
8281            updateEventDispatchingLocked();
8282
8283            if (!mSleeping) {
8284                mSleeping = true;
8285                mStackSupervisor.goingToSleepLocked();
8286
8287                // Initialize the wake times of all processes.
8288                checkExcessivePowerUsageLocked(false);
8289                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8290                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8291                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8292            }
8293        }
8294    }
8295
8296    @Override
8297    public boolean shutdown(int timeout) {
8298        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8299                != PackageManager.PERMISSION_GRANTED) {
8300            throw new SecurityException("Requires permission "
8301                    + android.Manifest.permission.SHUTDOWN);
8302        }
8303
8304        boolean timedout = false;
8305
8306        synchronized(this) {
8307            mShuttingDown = true;
8308            updateEventDispatchingLocked();
8309            timedout = mStackSupervisor.shutdownLocked(timeout);
8310        }
8311
8312        mAppOpsService.shutdown();
8313        mUsageStatsService.shutdown();
8314        mBatteryStatsService.shutdown();
8315        synchronized (this) {
8316            mProcessStats.shutdownLocked();
8317        }
8318
8319        return timedout;
8320    }
8321
8322    public final void activitySlept(IBinder token) {
8323        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8324
8325        final long origId = Binder.clearCallingIdentity();
8326
8327        synchronized (this) {
8328            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8329            if (r != null) {
8330                mStackSupervisor.activitySleptLocked(r);
8331            }
8332        }
8333
8334        Binder.restoreCallingIdentity(origId);
8335    }
8336
8337    void logLockScreen(String msg) {
8338        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8339                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8340                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8341                mStackSupervisor.mDismissKeyguardOnNextActivity);
8342    }
8343
8344    private void comeOutOfSleepIfNeededLocked() {
8345        if (!mWentToSleep && !mLockScreenShown) {
8346            if (mSleeping) {
8347                mSleeping = false;
8348                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8349            }
8350        }
8351    }
8352
8353    public void wakingUp() {
8354        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8355                != PackageManager.PERMISSION_GRANTED) {
8356            throw new SecurityException("Requires permission "
8357                    + android.Manifest.permission.DEVICE_POWER);
8358        }
8359
8360        synchronized(this) {
8361            mWentToSleep = false;
8362            updateEventDispatchingLocked();
8363            comeOutOfSleepIfNeededLocked();
8364        }
8365    }
8366
8367    private void updateEventDispatchingLocked() {
8368        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8369    }
8370
8371    public void setLockScreenShown(boolean shown) {
8372        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8373                != PackageManager.PERMISSION_GRANTED) {
8374            throw new SecurityException("Requires permission "
8375                    + android.Manifest.permission.DEVICE_POWER);
8376        }
8377
8378        synchronized(this) {
8379            long ident = Binder.clearCallingIdentity();
8380            try {
8381                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8382                mLockScreenShown = shown;
8383                comeOutOfSleepIfNeededLocked();
8384            } finally {
8385                Binder.restoreCallingIdentity(ident);
8386            }
8387        }
8388    }
8389
8390    public void stopAppSwitches() {
8391        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8392                != PackageManager.PERMISSION_GRANTED) {
8393            throw new SecurityException("Requires permission "
8394                    + android.Manifest.permission.STOP_APP_SWITCHES);
8395        }
8396
8397        synchronized(this) {
8398            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8399                    + APP_SWITCH_DELAY_TIME;
8400            mDidAppSwitch = false;
8401            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8402            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8403            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8404        }
8405    }
8406
8407    public void resumeAppSwitches() {
8408        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8409                != PackageManager.PERMISSION_GRANTED) {
8410            throw new SecurityException("Requires permission "
8411                    + android.Manifest.permission.STOP_APP_SWITCHES);
8412        }
8413
8414        synchronized(this) {
8415            // Note that we don't execute any pending app switches... we will
8416            // let those wait until either the timeout, or the next start
8417            // activity request.
8418            mAppSwitchesAllowedTime = 0;
8419        }
8420    }
8421
8422    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8423            String name) {
8424        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8425            return true;
8426        }
8427
8428        final int perm = checkComponentPermission(
8429                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8430                callingUid, -1, true);
8431        if (perm == PackageManager.PERMISSION_GRANTED) {
8432            return true;
8433        }
8434
8435        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8436        return false;
8437    }
8438
8439    public void setDebugApp(String packageName, boolean waitForDebugger,
8440            boolean persistent) {
8441        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8442                "setDebugApp()");
8443
8444        long ident = Binder.clearCallingIdentity();
8445        try {
8446            // Note that this is not really thread safe if there are multiple
8447            // callers into it at the same time, but that's not a situation we
8448            // care about.
8449            if (persistent) {
8450                final ContentResolver resolver = mContext.getContentResolver();
8451                Settings.Global.putString(
8452                    resolver, Settings.Global.DEBUG_APP,
8453                    packageName);
8454                Settings.Global.putInt(
8455                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8456                    waitForDebugger ? 1 : 0);
8457            }
8458
8459            synchronized (this) {
8460                if (!persistent) {
8461                    mOrigDebugApp = mDebugApp;
8462                    mOrigWaitForDebugger = mWaitForDebugger;
8463                }
8464                mDebugApp = packageName;
8465                mWaitForDebugger = waitForDebugger;
8466                mDebugTransient = !persistent;
8467                if (packageName != null) {
8468                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8469                            false, UserHandle.USER_ALL, "set debug app");
8470                }
8471            }
8472        } finally {
8473            Binder.restoreCallingIdentity(ident);
8474        }
8475    }
8476
8477    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8478        synchronized (this) {
8479            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8480            if (!isDebuggable) {
8481                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8482                    throw new SecurityException("Process not debuggable: " + app.packageName);
8483                }
8484            }
8485
8486            mOpenGlTraceApp = processName;
8487        }
8488    }
8489
8490    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8491            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8492        synchronized (this) {
8493            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8494            if (!isDebuggable) {
8495                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8496                    throw new SecurityException("Process not debuggable: " + app.packageName);
8497                }
8498            }
8499            mProfileApp = processName;
8500            mProfileFile = profileFile;
8501            if (mProfileFd != null) {
8502                try {
8503                    mProfileFd.close();
8504                } catch (IOException e) {
8505                }
8506                mProfileFd = null;
8507            }
8508            mProfileFd = profileFd;
8509            mProfileType = 0;
8510            mAutoStopProfiler = autoStopProfiler;
8511        }
8512    }
8513
8514    @Override
8515    public void setAlwaysFinish(boolean enabled) {
8516        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8517                "setAlwaysFinish()");
8518
8519        Settings.Global.putInt(
8520                mContext.getContentResolver(),
8521                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8522
8523        synchronized (this) {
8524            mAlwaysFinishActivities = enabled;
8525        }
8526    }
8527
8528    @Override
8529    public void setActivityController(IActivityController controller) {
8530        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8531                "setActivityController()");
8532        synchronized (this) {
8533            mController = controller;
8534            Watchdog.getInstance().setActivityController(controller);
8535        }
8536    }
8537
8538    @Override
8539    public void setUserIsMonkey(boolean userIsMonkey) {
8540        synchronized (this) {
8541            synchronized (mPidsSelfLocked) {
8542                final int callingPid = Binder.getCallingPid();
8543                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8544                if (precessRecord == null) {
8545                    throw new SecurityException("Unknown process: " + callingPid);
8546                }
8547                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8548                    throw new SecurityException("Only an instrumentation process "
8549                            + "with a UiAutomation can call setUserIsMonkey");
8550                }
8551            }
8552            mUserIsMonkey = userIsMonkey;
8553        }
8554    }
8555
8556    @Override
8557    public boolean isUserAMonkey() {
8558        synchronized (this) {
8559            // If there is a controller also implies the user is a monkey.
8560            return (mUserIsMonkey || mController != null);
8561        }
8562    }
8563
8564    public void requestBugReport() {
8565        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8566        SystemProperties.set("ctl.start", "bugreport");
8567    }
8568
8569    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8570        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8571    }
8572
8573    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8574        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8575            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8576        }
8577        return KEY_DISPATCHING_TIMEOUT;
8578    }
8579
8580    @Override
8581    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8582        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8583                != PackageManager.PERMISSION_GRANTED) {
8584            throw new SecurityException("Requires permission "
8585                    + android.Manifest.permission.FILTER_EVENTS);
8586        }
8587        ProcessRecord proc;
8588        long timeout;
8589        synchronized (this) {
8590            synchronized (mPidsSelfLocked) {
8591                proc = mPidsSelfLocked.get(pid);
8592            }
8593            timeout = getInputDispatchingTimeoutLocked(proc);
8594        }
8595
8596        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8597            return -1;
8598        }
8599
8600        return timeout;
8601    }
8602
8603    /**
8604     * Handle input dispatching timeouts.
8605     * Returns whether input dispatching should be aborted or not.
8606     */
8607    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8608            final ActivityRecord activity, final ActivityRecord parent,
8609            final boolean aboveSystem, String reason) {
8610        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8611                != PackageManager.PERMISSION_GRANTED) {
8612            throw new SecurityException("Requires permission "
8613                    + android.Manifest.permission.FILTER_EVENTS);
8614        }
8615
8616        final String annotation;
8617        if (reason == null) {
8618            annotation = "Input dispatching timed out";
8619        } else {
8620            annotation = "Input dispatching timed out (" + reason + ")";
8621        }
8622
8623        if (proc != null) {
8624            synchronized (this) {
8625                if (proc.debugging) {
8626                    return false;
8627                }
8628
8629                if (mDidDexOpt) {
8630                    // Give more time since we were dexopting.
8631                    mDidDexOpt = false;
8632                    return false;
8633                }
8634
8635                if (proc.instrumentationClass != null) {
8636                    Bundle info = new Bundle();
8637                    info.putString("shortMsg", "keyDispatchingTimedOut");
8638                    info.putString("longMsg", annotation);
8639                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8640                    return true;
8641                }
8642            }
8643            mHandler.post(new Runnable() {
8644                @Override
8645                public void run() {
8646                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8647                }
8648            });
8649        }
8650
8651        return true;
8652    }
8653
8654    public Bundle getAssistContextExtras(int requestType) {
8655        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8656                "getAssistContextExtras()");
8657        PendingAssistExtras pae;
8658        Bundle extras = new Bundle();
8659        synchronized (this) {
8660            ActivityRecord activity = getFocusedStack().mResumedActivity;
8661            if (activity == null) {
8662                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8663                return null;
8664            }
8665            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8666            if (activity.app == null || activity.app.thread == null) {
8667                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8668                return extras;
8669            }
8670            if (activity.app.pid == Binder.getCallingPid()) {
8671                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8672                return extras;
8673            }
8674            pae = new PendingAssistExtras(activity);
8675            try {
8676                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8677                        requestType);
8678                mPendingAssistExtras.add(pae);
8679                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8680            } catch (RemoteException e) {
8681                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8682                return extras;
8683            }
8684        }
8685        synchronized (pae) {
8686            while (!pae.haveResult) {
8687                try {
8688                    pae.wait();
8689                } catch (InterruptedException e) {
8690                }
8691            }
8692            if (pae.result != null) {
8693                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8694            }
8695        }
8696        synchronized (this) {
8697            mPendingAssistExtras.remove(pae);
8698            mHandler.removeCallbacks(pae);
8699        }
8700        return extras;
8701    }
8702
8703    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8704        PendingAssistExtras pae = (PendingAssistExtras)token;
8705        synchronized (pae) {
8706            pae.result = extras;
8707            pae.haveResult = true;
8708            pae.notifyAll();
8709        }
8710    }
8711
8712    public void registerProcessObserver(IProcessObserver observer) {
8713        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8714                "registerProcessObserver()");
8715        synchronized (this) {
8716            mProcessObservers.register(observer);
8717        }
8718    }
8719
8720    @Override
8721    public void unregisterProcessObserver(IProcessObserver observer) {
8722        synchronized (this) {
8723            mProcessObservers.unregister(observer);
8724        }
8725    }
8726
8727    @Override
8728    public boolean convertFromTranslucent(IBinder token) {
8729        final long origId = Binder.clearCallingIdentity();
8730        try {
8731            synchronized (this) {
8732                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8733                if (r == null) {
8734                    return false;
8735                }
8736                if (r.changeWindowTranslucency(true)) {
8737                    mWindowManager.setAppFullscreen(token, true);
8738                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8739                    return true;
8740                }
8741                return false;
8742            }
8743        } finally {
8744            Binder.restoreCallingIdentity(origId);
8745        }
8746    }
8747
8748    @Override
8749    public boolean convertToTranslucent(IBinder token) {
8750        final long origId = Binder.clearCallingIdentity();
8751        try {
8752            synchronized (this) {
8753                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8754                if (r == null) {
8755                    return false;
8756                }
8757                if (r.changeWindowTranslucency(false)) {
8758                    r.task.stack.convertToTranslucent(r);
8759                    mWindowManager.setAppFullscreen(token, false);
8760                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8761                    return true;
8762                }
8763                return false;
8764            }
8765        } finally {
8766            Binder.restoreCallingIdentity(origId);
8767        }
8768    }
8769
8770    @Override
8771    public void setImmersive(IBinder token, boolean immersive) {
8772        synchronized(this) {
8773            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8774            if (r == null) {
8775                throw new IllegalArgumentException();
8776            }
8777            r.immersive = immersive;
8778
8779            // update associated state if we're frontmost
8780            if (r == mFocusedActivity) {
8781                if (DEBUG_IMMERSIVE) {
8782                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8783                }
8784                applyUpdateLockStateLocked(r);
8785            }
8786        }
8787    }
8788
8789    @Override
8790    public boolean isImmersive(IBinder token) {
8791        synchronized (this) {
8792            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8793            if (r == null) {
8794                throw new IllegalArgumentException();
8795            }
8796            return r.immersive;
8797        }
8798    }
8799
8800    public boolean isTopActivityImmersive() {
8801        enforceNotIsolatedCaller("startActivity");
8802        synchronized (this) {
8803            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8804            return (r != null) ? r.immersive : false;
8805        }
8806    }
8807
8808    public final void enterSafeMode() {
8809        synchronized(this) {
8810            // It only makes sense to do this before the system is ready
8811            // and started launching other packages.
8812            if (!mSystemReady) {
8813                try {
8814                    AppGlobals.getPackageManager().enterSafeMode();
8815                } catch (RemoteException e) {
8816                }
8817            }
8818        }
8819    }
8820
8821    public final void showSafeModeOverlay() {
8822        View v = LayoutInflater.from(mContext).inflate(
8823                com.android.internal.R.layout.safe_mode, null);
8824        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8825        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8826        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8827        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8828        lp.gravity = Gravity.BOTTOM | Gravity.START;
8829        lp.format = v.getBackground().getOpacity();
8830        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8831                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8832        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8833        ((WindowManager)mContext.getSystemService(
8834                Context.WINDOW_SERVICE)).addView(v, lp);
8835    }
8836
8837    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8838        if (!(sender instanceof PendingIntentRecord)) {
8839            return;
8840        }
8841        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8842        synchronized (stats) {
8843            if (mBatteryStatsService.isOnBattery()) {
8844                mBatteryStatsService.enforceCallingPermission();
8845                PendingIntentRecord rec = (PendingIntentRecord)sender;
8846                int MY_UID = Binder.getCallingUid();
8847                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8848                BatteryStatsImpl.Uid.Pkg pkg =
8849                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8850                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8851                pkg.incWakeupsLocked();
8852            }
8853        }
8854    }
8855
8856    public boolean killPids(int[] pids, String pReason, boolean secure) {
8857        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8858            throw new SecurityException("killPids only available to the system");
8859        }
8860        String reason = (pReason == null) ? "Unknown" : pReason;
8861        // XXX Note: don't acquire main activity lock here, because the window
8862        // manager calls in with its locks held.
8863
8864        boolean killed = false;
8865        synchronized (mPidsSelfLocked) {
8866            int[] types = new int[pids.length];
8867            int worstType = 0;
8868            for (int i=0; i<pids.length; i++) {
8869                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8870                if (proc != null) {
8871                    int type = proc.setAdj;
8872                    types[i] = type;
8873                    if (type > worstType) {
8874                        worstType = type;
8875                    }
8876                }
8877            }
8878
8879            // If the worst oom_adj is somewhere in the cached proc LRU range,
8880            // then constrain it so we will kill all cached procs.
8881            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8882                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8883                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8884            }
8885
8886            // If this is not a secure call, don't let it kill processes that
8887            // are important.
8888            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8889                worstType = ProcessList.SERVICE_ADJ;
8890            }
8891
8892            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8893            for (int i=0; i<pids.length; i++) {
8894                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8895                if (proc == null) {
8896                    continue;
8897                }
8898                int adj = proc.setAdj;
8899                if (adj >= worstType && !proc.killedByAm) {
8900                    killUnneededProcessLocked(proc, reason);
8901                    killed = true;
8902                }
8903            }
8904        }
8905        return killed;
8906    }
8907
8908    @Override
8909    public void killUid(int uid, String reason) {
8910        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8911            throw new SecurityException("killUid only available to the system");
8912        }
8913        synchronized (this) {
8914            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8915                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8916                    reason != null ? reason : "kill uid");
8917        }
8918    }
8919
8920    @Override
8921    public boolean killProcessesBelowForeground(String reason) {
8922        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8923            throw new SecurityException("killProcessesBelowForeground() only available to system");
8924        }
8925
8926        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8927    }
8928
8929    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8930        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8931            throw new SecurityException("killProcessesBelowAdj() only available to system");
8932        }
8933
8934        boolean killed = false;
8935        synchronized (mPidsSelfLocked) {
8936            final int size = mPidsSelfLocked.size();
8937            for (int i = 0; i < size; i++) {
8938                final int pid = mPidsSelfLocked.keyAt(i);
8939                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8940                if (proc == null) continue;
8941
8942                final int adj = proc.setAdj;
8943                if (adj > belowAdj && !proc.killedByAm) {
8944                    killUnneededProcessLocked(proc, reason);
8945                    killed = true;
8946                }
8947            }
8948        }
8949        return killed;
8950    }
8951
8952    @Override
8953    public void hang(final IBinder who, boolean allowRestart) {
8954        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8955                != PackageManager.PERMISSION_GRANTED) {
8956            throw new SecurityException("Requires permission "
8957                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8958        }
8959
8960        final IBinder.DeathRecipient death = new DeathRecipient() {
8961            @Override
8962            public void binderDied() {
8963                synchronized (this) {
8964                    notifyAll();
8965                }
8966            }
8967        };
8968
8969        try {
8970            who.linkToDeath(death, 0);
8971        } catch (RemoteException e) {
8972            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8973            return;
8974        }
8975
8976        synchronized (this) {
8977            Watchdog.getInstance().setAllowRestart(allowRestart);
8978            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8979            synchronized (death) {
8980                while (who.isBinderAlive()) {
8981                    try {
8982                        death.wait();
8983                    } catch (InterruptedException e) {
8984                    }
8985                }
8986            }
8987            Watchdog.getInstance().setAllowRestart(true);
8988        }
8989    }
8990
8991    @Override
8992    public void restart() {
8993        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8994                != PackageManager.PERMISSION_GRANTED) {
8995            throw new SecurityException("Requires permission "
8996                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8997        }
8998
8999        Log.i(TAG, "Sending shutdown broadcast...");
9000
9001        BroadcastReceiver br = new BroadcastReceiver() {
9002            @Override public void onReceive(Context context, Intent intent) {
9003                // Now the broadcast is done, finish up the low-level shutdown.
9004                Log.i(TAG, "Shutting down activity manager...");
9005                shutdown(10000);
9006                Log.i(TAG, "Shutdown complete, restarting!");
9007                Process.killProcess(Process.myPid());
9008                System.exit(10);
9009            }
9010        };
9011
9012        // First send the high-level shut down broadcast.
9013        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9014        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9015        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9016        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9017        mContext.sendOrderedBroadcastAsUser(intent,
9018                UserHandle.ALL, null, br, mHandler, 0, null, null);
9019        */
9020        br.onReceive(mContext, intent);
9021    }
9022
9023    private long getLowRamTimeSinceIdle(long now) {
9024        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9025    }
9026
9027    @Override
9028    public void performIdleMaintenance() {
9029        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9030                != PackageManager.PERMISSION_GRANTED) {
9031            throw new SecurityException("Requires permission "
9032                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9033        }
9034
9035        synchronized (this) {
9036            final long now = SystemClock.uptimeMillis();
9037            final long timeSinceLastIdle = now - mLastIdleTime;
9038            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9039            mLastIdleTime = now;
9040            mLowRamTimeSinceLastIdle = 0;
9041            if (mLowRamStartTime != 0) {
9042                mLowRamStartTime = now;
9043            }
9044
9045            StringBuilder sb = new StringBuilder(128);
9046            sb.append("Idle maintenance over ");
9047            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9048            sb.append(" low RAM for ");
9049            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9050            Slog.i(TAG, sb.toString());
9051
9052            // If at least 1/3 of our time since the last idle period has been spent
9053            // with RAM low, then we want to kill processes.
9054            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9055
9056            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9057                ProcessRecord proc = mLruProcesses.get(i);
9058                if (proc.notCachedSinceIdle) {
9059                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9060                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9061                        if (doKilling && proc.initialIdlePss != 0
9062                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9063                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9064                                    + " from " + proc.initialIdlePss + ")");
9065                        }
9066                    }
9067                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9068                    proc.notCachedSinceIdle = true;
9069                    proc.initialIdlePss = 0;
9070                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9071                            mSleeping, now);
9072                }
9073            }
9074
9075            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9076            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9077        }
9078    }
9079
9080    public final void startRunning(String pkg, String cls, String action,
9081            String data) {
9082        synchronized(this) {
9083            if (mStartRunning) {
9084                return;
9085            }
9086            mStartRunning = true;
9087            mTopComponent = pkg != null && cls != null
9088                    ? new ComponentName(pkg, cls) : null;
9089            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9090            mTopData = data;
9091            if (!mSystemReady) {
9092                return;
9093            }
9094        }
9095
9096        systemReady(null);
9097    }
9098
9099    private void retrieveSettings() {
9100        final ContentResolver resolver = mContext.getContentResolver();
9101        String debugApp = Settings.Global.getString(
9102            resolver, Settings.Global.DEBUG_APP);
9103        boolean waitForDebugger = Settings.Global.getInt(
9104            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9105        boolean alwaysFinishActivities = Settings.Global.getInt(
9106            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9107        boolean forceRtl = Settings.Global.getInt(
9108                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9109        // Transfer any global setting for forcing RTL layout, into a System Property
9110        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9111
9112        Configuration configuration = new Configuration();
9113        Settings.System.getConfiguration(resolver, configuration);
9114        if (forceRtl) {
9115            // This will take care of setting the correct layout direction flags
9116            configuration.setLayoutDirection(configuration.locale);
9117        }
9118
9119        synchronized (this) {
9120            mDebugApp = mOrigDebugApp = debugApp;
9121            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9122            mAlwaysFinishActivities = alwaysFinishActivities;
9123            // This happens before any activities are started, so we can
9124            // change mConfiguration in-place.
9125            updateConfigurationLocked(configuration, null, false, true);
9126            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9127        }
9128    }
9129
9130    public boolean testIsSystemReady() {
9131        // no need to synchronize(this) just to read & return the value
9132        return mSystemReady;
9133    }
9134
9135    private static File getCalledPreBootReceiversFile() {
9136        File dataDir = Environment.getDataDirectory();
9137        File systemDir = new File(dataDir, "system");
9138        File fname = new File(systemDir, "called_pre_boots.dat");
9139        return fname;
9140    }
9141
9142    static final int LAST_DONE_VERSION = 10000;
9143
9144    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9145        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9146        File file = getCalledPreBootReceiversFile();
9147        FileInputStream fis = null;
9148        try {
9149            fis = new FileInputStream(file);
9150            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9151            int fvers = dis.readInt();
9152            if (fvers == LAST_DONE_VERSION) {
9153                String vers = dis.readUTF();
9154                String codename = dis.readUTF();
9155                String build = dis.readUTF();
9156                if (android.os.Build.VERSION.RELEASE.equals(vers)
9157                        && android.os.Build.VERSION.CODENAME.equals(codename)
9158                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9159                    int num = dis.readInt();
9160                    while (num > 0) {
9161                        num--;
9162                        String pkg = dis.readUTF();
9163                        String cls = dis.readUTF();
9164                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9165                    }
9166                }
9167            }
9168        } catch (FileNotFoundException e) {
9169        } catch (IOException e) {
9170            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9171        } finally {
9172            if (fis != null) {
9173                try {
9174                    fis.close();
9175                } catch (IOException e) {
9176                }
9177            }
9178        }
9179        return lastDoneReceivers;
9180    }
9181
9182    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9183        File file = getCalledPreBootReceiversFile();
9184        FileOutputStream fos = null;
9185        DataOutputStream dos = null;
9186        try {
9187            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9188            fos = new FileOutputStream(file);
9189            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9190            dos.writeInt(LAST_DONE_VERSION);
9191            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9192            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9193            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9194            dos.writeInt(list.size());
9195            for (int i=0; i<list.size(); i++) {
9196                dos.writeUTF(list.get(i).getPackageName());
9197                dos.writeUTF(list.get(i).getClassName());
9198            }
9199        } catch (IOException e) {
9200            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9201            file.delete();
9202        } finally {
9203            FileUtils.sync(fos);
9204            if (dos != null) {
9205                try {
9206                    dos.close();
9207                } catch (IOException e) {
9208                    // TODO Auto-generated catch block
9209                    e.printStackTrace();
9210                }
9211            }
9212        }
9213    }
9214
9215    public void systemReady(final Runnable goingCallback) {
9216        synchronized(this) {
9217            if (mSystemReady) {
9218                if (goingCallback != null) goingCallback.run();
9219                return;
9220            }
9221
9222            // Check to see if there are any update receivers to run.
9223            if (!mDidUpdate) {
9224                if (mWaitingUpdate) {
9225                    return;
9226                }
9227                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9228                List<ResolveInfo> ris = null;
9229                try {
9230                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9231                            intent, null, 0, 0);
9232                } catch (RemoteException e) {
9233                }
9234                if (ris != null) {
9235                    for (int i=ris.size()-1; i>=0; i--) {
9236                        if ((ris.get(i).activityInfo.applicationInfo.flags
9237                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9238                            ris.remove(i);
9239                        }
9240                    }
9241                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9242
9243                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9244
9245                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9246                    for (int i=0; i<ris.size(); i++) {
9247                        ActivityInfo ai = ris.get(i).activityInfo;
9248                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9249                        if (lastDoneReceivers.contains(comp)) {
9250                            // We already did the pre boot receiver for this app with the current
9251                            // platform version, so don't do it again...
9252                            ris.remove(i);
9253                            i--;
9254                            // ...however, do keep it as one that has been done, so we don't
9255                            // forget about it when rewriting the file of last done receivers.
9256                            doneReceivers.add(comp);
9257                        }
9258                    }
9259
9260                    final int[] users = getUsersLocked();
9261                    for (int i=0; i<ris.size(); i++) {
9262                        ActivityInfo ai = ris.get(i).activityInfo;
9263                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9264                        doneReceivers.add(comp);
9265                        intent.setComponent(comp);
9266                        for (int j=0; j<users.length; j++) {
9267                            IIntentReceiver finisher = null;
9268                            if (i == ris.size()-1 && j == users.length-1) {
9269                                finisher = new IIntentReceiver.Stub() {
9270                                    public void performReceive(Intent intent, int resultCode,
9271                                            String data, Bundle extras, boolean ordered,
9272                                            boolean sticky, int sendingUser) {
9273                                        // The raw IIntentReceiver interface is called
9274                                        // with the AM lock held, so redispatch to
9275                                        // execute our code without the lock.
9276                                        mHandler.post(new Runnable() {
9277                                            public void run() {
9278                                                synchronized (ActivityManagerService.this) {
9279                                                    mDidUpdate = true;
9280                                                }
9281                                                writeLastDonePreBootReceivers(doneReceivers);
9282                                                showBootMessage(mContext.getText(
9283                                                        R.string.android_upgrading_complete),
9284                                                        false);
9285                                                systemReady(goingCallback);
9286                                            }
9287                                        });
9288                                    }
9289                                };
9290                            }
9291                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9292                                    + " for user " + users[j]);
9293                            broadcastIntentLocked(null, null, intent, null, finisher,
9294                                    0, null, null, null, AppOpsManager.OP_NONE,
9295                                    true, false, MY_PID, Process.SYSTEM_UID,
9296                                    users[j]);
9297                            if (finisher != null) {
9298                                mWaitingUpdate = true;
9299                            }
9300                        }
9301                    }
9302                }
9303                if (mWaitingUpdate) {
9304                    return;
9305                }
9306                mDidUpdate = true;
9307            }
9308
9309            mAppOpsService.systemReady();
9310            mSystemReady = true;
9311            if (!mStartRunning) {
9312                return;
9313            }
9314        }
9315
9316        ArrayList<ProcessRecord> procsToKill = null;
9317        synchronized(mPidsSelfLocked) {
9318            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9319                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9320                if (!isAllowedWhileBooting(proc.info)){
9321                    if (procsToKill == null) {
9322                        procsToKill = new ArrayList<ProcessRecord>();
9323                    }
9324                    procsToKill.add(proc);
9325                }
9326            }
9327        }
9328
9329        synchronized(this) {
9330            if (procsToKill != null) {
9331                for (int i=procsToKill.size()-1; i>=0; i--) {
9332                    ProcessRecord proc = procsToKill.get(i);
9333                    Slog.i(TAG, "Removing system update proc: " + proc);
9334                    removeProcessLocked(proc, true, false, "system update done");
9335                }
9336            }
9337
9338            // Now that we have cleaned up any update processes, we
9339            // are ready to start launching real processes and know that
9340            // we won't trample on them any more.
9341            mProcessesReady = true;
9342        }
9343
9344        Slog.i(TAG, "System now ready");
9345        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9346            SystemClock.uptimeMillis());
9347
9348        synchronized(this) {
9349            // Make sure we have no pre-ready processes sitting around.
9350
9351            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9352                ResolveInfo ri = mContext.getPackageManager()
9353                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9354                                STOCK_PM_FLAGS);
9355                CharSequence errorMsg = null;
9356                if (ri != null) {
9357                    ActivityInfo ai = ri.activityInfo;
9358                    ApplicationInfo app = ai.applicationInfo;
9359                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9360                        mTopAction = Intent.ACTION_FACTORY_TEST;
9361                        mTopData = null;
9362                        mTopComponent = new ComponentName(app.packageName,
9363                                ai.name);
9364                    } else {
9365                        errorMsg = mContext.getResources().getText(
9366                                com.android.internal.R.string.factorytest_not_system);
9367                    }
9368                } else {
9369                    errorMsg = mContext.getResources().getText(
9370                            com.android.internal.R.string.factorytest_no_action);
9371                }
9372                if (errorMsg != null) {
9373                    mTopAction = null;
9374                    mTopData = null;
9375                    mTopComponent = null;
9376                    Message msg = Message.obtain();
9377                    msg.what = SHOW_FACTORY_ERROR_MSG;
9378                    msg.getData().putCharSequence("msg", errorMsg);
9379                    mHandler.sendMessage(msg);
9380                }
9381            }
9382        }
9383
9384        retrieveSettings();
9385
9386        synchronized (this) {
9387            readGrantedUriPermissionsLocked();
9388        }
9389
9390        if (goingCallback != null) goingCallback.run();
9391
9392        synchronized (this) {
9393            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9394                try {
9395                    List apps = AppGlobals.getPackageManager().
9396                        getPersistentApplications(STOCK_PM_FLAGS);
9397                    if (apps != null) {
9398                        int N = apps.size();
9399                        int i;
9400                        for (i=0; i<N; i++) {
9401                            ApplicationInfo info
9402                                = (ApplicationInfo)apps.get(i);
9403                            if (info != null &&
9404                                    !info.packageName.equals("android")) {
9405                                addAppLocked(info, false);
9406                            }
9407                        }
9408                    }
9409                } catch (RemoteException ex) {
9410                    // pm is in same process, this will never happen.
9411                }
9412            }
9413
9414            // Start up initial activity.
9415            mBooting = true;
9416
9417            try {
9418                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9419                    Message msg = Message.obtain();
9420                    msg.what = SHOW_UID_ERROR_MSG;
9421                    mHandler.sendMessage(msg);
9422                }
9423            } catch (RemoteException e) {
9424            }
9425
9426            long ident = Binder.clearCallingIdentity();
9427            try {
9428                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9429                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9430                        | Intent.FLAG_RECEIVER_FOREGROUND);
9431                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9432                broadcastIntentLocked(null, null, intent,
9433                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9434                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9435                intent = new Intent(Intent.ACTION_USER_STARTING);
9436                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9437                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9438                broadcastIntentLocked(null, null, intent,
9439                        null, new IIntentReceiver.Stub() {
9440                            @Override
9441                            public void performReceive(Intent intent, int resultCode, String data,
9442                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9443                                    throws RemoteException {
9444                            }
9445                        }, 0, null, null,
9446                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9447                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9448            } finally {
9449                Binder.restoreCallingIdentity(ident);
9450            }
9451            mStackSupervisor.resumeTopActivitiesLocked();
9452            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9453        }
9454    }
9455
9456    private boolean makeAppCrashingLocked(ProcessRecord app,
9457            String shortMsg, String longMsg, String stackTrace) {
9458        app.crashing = true;
9459        app.crashingReport = generateProcessError(app,
9460                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9461        startAppProblemLocked(app);
9462        app.stopFreezingAllLocked();
9463        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9464    }
9465
9466    private void makeAppNotRespondingLocked(ProcessRecord app,
9467            String activity, String shortMsg, String longMsg) {
9468        app.notResponding = true;
9469        app.notRespondingReport = generateProcessError(app,
9470                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9471                activity, shortMsg, longMsg, null);
9472        startAppProblemLocked(app);
9473        app.stopFreezingAllLocked();
9474    }
9475
9476    /**
9477     * Generate a process error record, suitable for attachment to a ProcessRecord.
9478     *
9479     * @param app The ProcessRecord in which the error occurred.
9480     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9481     *                      ActivityManager.AppErrorStateInfo
9482     * @param activity The activity associated with the crash, if known.
9483     * @param shortMsg Short message describing the crash.
9484     * @param longMsg Long message describing the crash.
9485     * @param stackTrace Full crash stack trace, may be null.
9486     *
9487     * @return Returns a fully-formed AppErrorStateInfo record.
9488     */
9489    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9490            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9491        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9492
9493        report.condition = condition;
9494        report.processName = app.processName;
9495        report.pid = app.pid;
9496        report.uid = app.info.uid;
9497        report.tag = activity;
9498        report.shortMsg = shortMsg;
9499        report.longMsg = longMsg;
9500        report.stackTrace = stackTrace;
9501
9502        return report;
9503    }
9504
9505    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9506        synchronized (this) {
9507            app.crashing = false;
9508            app.crashingReport = null;
9509            app.notResponding = false;
9510            app.notRespondingReport = null;
9511            if (app.anrDialog == fromDialog) {
9512                app.anrDialog = null;
9513            }
9514            if (app.waitDialog == fromDialog) {
9515                app.waitDialog = null;
9516            }
9517            if (app.pid > 0 && app.pid != MY_PID) {
9518                handleAppCrashLocked(app, null, null, null);
9519                killUnneededProcessLocked(app, "user request after error");
9520            }
9521        }
9522    }
9523
9524    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9525            String stackTrace) {
9526        long now = SystemClock.uptimeMillis();
9527
9528        Long crashTime;
9529        if (!app.isolated) {
9530            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9531        } else {
9532            crashTime = null;
9533        }
9534        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9535            // This process loses!
9536            Slog.w(TAG, "Process " + app.info.processName
9537                    + " has crashed too many times: killing!");
9538            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9539                    app.userId, app.info.processName, app.uid);
9540            mStackSupervisor.handleAppCrashLocked(app);
9541            if (!app.persistent) {
9542                // We don't want to start this process again until the user
9543                // explicitly does so...  but for persistent process, we really
9544                // need to keep it running.  If a persistent process is actually
9545                // repeatedly crashing, then badness for everyone.
9546                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9547                        app.info.processName);
9548                if (!app.isolated) {
9549                    // XXX We don't have a way to mark isolated processes
9550                    // as bad, since they don't have a peristent identity.
9551                    mBadProcesses.put(app.info.processName, app.uid,
9552                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9553                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9554                }
9555                app.bad = true;
9556                app.removed = true;
9557                // Don't let services in this process be restarted and potentially
9558                // annoy the user repeatedly.  Unless it is persistent, since those
9559                // processes run critical code.
9560                removeProcessLocked(app, false, false, "crash");
9561                mStackSupervisor.resumeTopActivitiesLocked();
9562                return false;
9563            }
9564            mStackSupervisor.resumeTopActivitiesLocked();
9565        } else {
9566            mStackSupervisor.finishTopRunningActivityLocked(app);
9567        }
9568
9569        // Bump up the crash count of any services currently running in the proc.
9570        for (int i=app.services.size()-1; i>=0; i--) {
9571            // Any services running in the application need to be placed
9572            // back in the pending list.
9573            ServiceRecord sr = app.services.valueAt(i);
9574            sr.crashCount++;
9575        }
9576
9577        // If the crashing process is what we consider to be the "home process" and it has been
9578        // replaced by a third-party app, clear the package preferred activities from packages
9579        // with a home activity running in the process to prevent a repeatedly crashing app
9580        // from blocking the user to manually clear the list.
9581        final ArrayList<ActivityRecord> activities = app.activities;
9582        if (app == mHomeProcess && activities.size() > 0
9583                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9584            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9585                final ActivityRecord r = activities.get(activityNdx);
9586                if (r.isHomeActivity()) {
9587                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9588                    try {
9589                        ActivityThread.getPackageManager()
9590                                .clearPackagePreferredActivities(r.packageName);
9591                    } catch (RemoteException c) {
9592                        // pm is in same process, this will never happen.
9593                    }
9594                }
9595            }
9596        }
9597
9598        if (!app.isolated) {
9599            // XXX Can't keep track of crash times for isolated processes,
9600            // because they don't have a perisistent identity.
9601            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9602        }
9603
9604        return true;
9605    }
9606
9607    void startAppProblemLocked(ProcessRecord app) {
9608        if (app.userId == mCurrentUserId) {
9609            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9610                    mContext, app.info.packageName, app.info.flags);
9611        } else {
9612            // If this app is not running under the current user, then we
9613            // can't give it a report button because that would require
9614            // launching the report UI under a different user.
9615            app.errorReportReceiver = null;
9616        }
9617        skipCurrentReceiverLocked(app);
9618    }
9619
9620    void skipCurrentReceiverLocked(ProcessRecord app) {
9621        for (BroadcastQueue queue : mBroadcastQueues) {
9622            queue.skipCurrentReceiverLocked(app);
9623        }
9624    }
9625
9626    /**
9627     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9628     * The application process will exit immediately after this call returns.
9629     * @param app object of the crashing app, null for the system server
9630     * @param crashInfo describing the exception
9631     */
9632    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9633        ProcessRecord r = findAppProcess(app, "Crash");
9634        final String processName = app == null ? "system_server"
9635                : (r == null ? "unknown" : r.processName);
9636
9637        handleApplicationCrashInner("crash", r, processName, crashInfo);
9638    }
9639
9640    /* Native crash reporting uses this inner version because it needs to be somewhat
9641     * decoupled from the AM-managed cleanup lifecycle
9642     */
9643    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9644            ApplicationErrorReport.CrashInfo crashInfo) {
9645        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9646                UserHandle.getUserId(Binder.getCallingUid()), processName,
9647                r == null ? -1 : r.info.flags,
9648                crashInfo.exceptionClassName,
9649                crashInfo.exceptionMessage,
9650                crashInfo.throwFileName,
9651                crashInfo.throwLineNumber);
9652
9653        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9654
9655        crashApplication(r, crashInfo);
9656    }
9657
9658    public void handleApplicationStrictModeViolation(
9659            IBinder app,
9660            int violationMask,
9661            StrictMode.ViolationInfo info) {
9662        ProcessRecord r = findAppProcess(app, "StrictMode");
9663        if (r == null) {
9664            return;
9665        }
9666
9667        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9668            Integer stackFingerprint = info.hashCode();
9669            boolean logIt = true;
9670            synchronized (mAlreadyLoggedViolatedStacks) {
9671                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9672                    logIt = false;
9673                    // TODO: sub-sample into EventLog for these, with
9674                    // the info.durationMillis?  Then we'd get
9675                    // the relative pain numbers, without logging all
9676                    // the stack traces repeatedly.  We'd want to do
9677                    // likewise in the client code, which also does
9678                    // dup suppression, before the Binder call.
9679                } else {
9680                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9681                        mAlreadyLoggedViolatedStacks.clear();
9682                    }
9683                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9684                }
9685            }
9686            if (logIt) {
9687                logStrictModeViolationToDropBox(r, info);
9688            }
9689        }
9690
9691        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9692            AppErrorResult result = new AppErrorResult();
9693            synchronized (this) {
9694                final long origId = Binder.clearCallingIdentity();
9695
9696                Message msg = Message.obtain();
9697                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9698                HashMap<String, Object> data = new HashMap<String, Object>();
9699                data.put("result", result);
9700                data.put("app", r);
9701                data.put("violationMask", violationMask);
9702                data.put("info", info);
9703                msg.obj = data;
9704                mHandler.sendMessage(msg);
9705
9706                Binder.restoreCallingIdentity(origId);
9707            }
9708            int res = result.get();
9709            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9710        }
9711    }
9712
9713    // Depending on the policy in effect, there could be a bunch of
9714    // these in quick succession so we try to batch these together to
9715    // minimize disk writes, number of dropbox entries, and maximize
9716    // compression, by having more fewer, larger records.
9717    private void logStrictModeViolationToDropBox(
9718            ProcessRecord process,
9719            StrictMode.ViolationInfo info) {
9720        if (info == null) {
9721            return;
9722        }
9723        final boolean isSystemApp = process == null ||
9724                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9725                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9726        final String processName = process == null ? "unknown" : process.processName;
9727        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9728        final DropBoxManager dbox = (DropBoxManager)
9729                mContext.getSystemService(Context.DROPBOX_SERVICE);
9730
9731        // Exit early if the dropbox isn't configured to accept this report type.
9732        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9733
9734        boolean bufferWasEmpty;
9735        boolean needsFlush;
9736        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9737        synchronized (sb) {
9738            bufferWasEmpty = sb.length() == 0;
9739            appendDropBoxProcessHeaders(process, processName, sb);
9740            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9741            sb.append("System-App: ").append(isSystemApp).append("\n");
9742            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9743            if (info.violationNumThisLoop != 0) {
9744                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9745            }
9746            if (info.numAnimationsRunning != 0) {
9747                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9748            }
9749            if (info.broadcastIntentAction != null) {
9750                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9751            }
9752            if (info.durationMillis != -1) {
9753                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9754            }
9755            if (info.numInstances != -1) {
9756                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9757            }
9758            if (info.tags != null) {
9759                for (String tag : info.tags) {
9760                    sb.append("Span-Tag: ").append(tag).append("\n");
9761                }
9762            }
9763            sb.append("\n");
9764            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9765                sb.append(info.crashInfo.stackTrace);
9766            }
9767            sb.append("\n");
9768
9769            // Only buffer up to ~64k.  Various logging bits truncate
9770            // things at 128k.
9771            needsFlush = (sb.length() > 64 * 1024);
9772        }
9773
9774        // Flush immediately if the buffer's grown too large, or this
9775        // is a non-system app.  Non-system apps are isolated with a
9776        // different tag & policy and not batched.
9777        //
9778        // Batching is useful during internal testing with
9779        // StrictMode settings turned up high.  Without batching,
9780        // thousands of separate files could be created on boot.
9781        if (!isSystemApp || needsFlush) {
9782            new Thread("Error dump: " + dropboxTag) {
9783                @Override
9784                public void run() {
9785                    String report;
9786                    synchronized (sb) {
9787                        report = sb.toString();
9788                        sb.delete(0, sb.length());
9789                        sb.trimToSize();
9790                    }
9791                    if (report.length() != 0) {
9792                        dbox.addText(dropboxTag, report);
9793                    }
9794                }
9795            }.start();
9796            return;
9797        }
9798
9799        // System app batching:
9800        if (!bufferWasEmpty) {
9801            // An existing dropbox-writing thread is outstanding, so
9802            // we don't need to start it up.  The existing thread will
9803            // catch the buffer appends we just did.
9804            return;
9805        }
9806
9807        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9808        // (After this point, we shouldn't access AMS internal data structures.)
9809        new Thread("Error dump: " + dropboxTag) {
9810            @Override
9811            public void run() {
9812                // 5 second sleep to let stacks arrive and be batched together
9813                try {
9814                    Thread.sleep(5000);  // 5 seconds
9815                } catch (InterruptedException e) {}
9816
9817                String errorReport;
9818                synchronized (mStrictModeBuffer) {
9819                    errorReport = mStrictModeBuffer.toString();
9820                    if (errorReport.length() == 0) {
9821                        return;
9822                    }
9823                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9824                    mStrictModeBuffer.trimToSize();
9825                }
9826                dbox.addText(dropboxTag, errorReport);
9827            }
9828        }.start();
9829    }
9830
9831    /**
9832     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9833     * @param app object of the crashing app, null for the system server
9834     * @param tag reported by the caller
9835     * @param crashInfo describing the context of the error
9836     * @return true if the process should exit immediately (WTF is fatal)
9837     */
9838    public boolean handleApplicationWtf(IBinder app, String tag,
9839            ApplicationErrorReport.CrashInfo crashInfo) {
9840        ProcessRecord r = findAppProcess(app, "WTF");
9841        final String processName = app == null ? "system_server"
9842                : (r == null ? "unknown" : r.processName);
9843
9844        EventLog.writeEvent(EventLogTags.AM_WTF,
9845                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9846                processName,
9847                r == null ? -1 : r.info.flags,
9848                tag, crashInfo.exceptionMessage);
9849
9850        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9851
9852        if (r != null && r.pid != Process.myPid() &&
9853                Settings.Global.getInt(mContext.getContentResolver(),
9854                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9855            crashApplication(r, crashInfo);
9856            return true;
9857        } else {
9858            return false;
9859        }
9860    }
9861
9862    /**
9863     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9864     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9865     */
9866    private ProcessRecord findAppProcess(IBinder app, String reason) {
9867        if (app == null) {
9868            return null;
9869        }
9870
9871        synchronized (this) {
9872            final int NP = mProcessNames.getMap().size();
9873            for (int ip=0; ip<NP; ip++) {
9874                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9875                final int NA = apps.size();
9876                for (int ia=0; ia<NA; ia++) {
9877                    ProcessRecord p = apps.valueAt(ia);
9878                    if (p.thread != null && p.thread.asBinder() == app) {
9879                        return p;
9880                    }
9881                }
9882            }
9883
9884            Slog.w(TAG, "Can't find mystery application for " + reason
9885                    + " from pid=" + Binder.getCallingPid()
9886                    + " uid=" + Binder.getCallingUid() + ": " + app);
9887            return null;
9888        }
9889    }
9890
9891    /**
9892     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9893     * to append various headers to the dropbox log text.
9894     */
9895    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9896            StringBuilder sb) {
9897        // Watchdog thread ends up invoking this function (with
9898        // a null ProcessRecord) to add the stack file to dropbox.
9899        // Do not acquire a lock on this (am) in such cases, as it
9900        // could cause a potential deadlock, if and when watchdog
9901        // is invoked due to unavailability of lock on am and it
9902        // would prevent watchdog from killing system_server.
9903        if (process == null) {
9904            sb.append("Process: ").append(processName).append("\n");
9905            return;
9906        }
9907        // Note: ProcessRecord 'process' is guarded by the service
9908        // instance.  (notably process.pkgList, which could otherwise change
9909        // concurrently during execution of this method)
9910        synchronized (this) {
9911            sb.append("Process: ").append(processName).append("\n");
9912            int flags = process.info.flags;
9913            IPackageManager pm = AppGlobals.getPackageManager();
9914            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9915            for (int ip=0; ip<process.pkgList.size(); ip++) {
9916                String pkg = process.pkgList.keyAt(ip);
9917                sb.append("Package: ").append(pkg);
9918                try {
9919                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9920                    if (pi != null) {
9921                        sb.append(" v").append(pi.versionCode);
9922                        if (pi.versionName != null) {
9923                            sb.append(" (").append(pi.versionName).append(")");
9924                        }
9925                    }
9926                } catch (RemoteException e) {
9927                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9928                }
9929                sb.append("\n");
9930            }
9931        }
9932    }
9933
9934    private static String processClass(ProcessRecord process) {
9935        if (process == null || process.pid == MY_PID) {
9936            return "system_server";
9937        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9938            return "system_app";
9939        } else {
9940            return "data_app";
9941        }
9942    }
9943
9944    /**
9945     * Write a description of an error (crash, WTF, ANR) to the drop box.
9946     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9947     * @param process which caused the error, null means the system server
9948     * @param activity which triggered the error, null if unknown
9949     * @param parent activity related to the error, null if unknown
9950     * @param subject line related to the error, null if absent
9951     * @param report in long form describing the error, null if absent
9952     * @param logFile to include in the report, null if none
9953     * @param crashInfo giving an application stack trace, null if absent
9954     */
9955    public void addErrorToDropBox(String eventType,
9956            ProcessRecord process, String processName, ActivityRecord activity,
9957            ActivityRecord parent, String subject,
9958            final String report, final File logFile,
9959            final ApplicationErrorReport.CrashInfo crashInfo) {
9960        // NOTE -- this must never acquire the ActivityManagerService lock,
9961        // otherwise the watchdog may be prevented from resetting the system.
9962
9963        final String dropboxTag = processClass(process) + "_" + eventType;
9964        final DropBoxManager dbox = (DropBoxManager)
9965                mContext.getSystemService(Context.DROPBOX_SERVICE);
9966
9967        // Exit early if the dropbox isn't configured to accept this report type.
9968        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9969
9970        final StringBuilder sb = new StringBuilder(1024);
9971        appendDropBoxProcessHeaders(process, processName, sb);
9972        if (activity != null) {
9973            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9974        }
9975        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9976            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9977        }
9978        if (parent != null && parent != activity) {
9979            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9980        }
9981        if (subject != null) {
9982            sb.append("Subject: ").append(subject).append("\n");
9983        }
9984        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9985        if (Debug.isDebuggerConnected()) {
9986            sb.append("Debugger: Connected\n");
9987        }
9988        sb.append("\n");
9989
9990        // Do the rest in a worker thread to avoid blocking the caller on I/O
9991        // (After this point, we shouldn't access AMS internal data structures.)
9992        Thread worker = new Thread("Error dump: " + dropboxTag) {
9993            @Override
9994            public void run() {
9995                if (report != null) {
9996                    sb.append(report);
9997                }
9998                if (logFile != null) {
9999                    try {
10000                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10001                                    "\n\n[[TRUNCATED]]"));
10002                    } catch (IOException e) {
10003                        Slog.e(TAG, "Error reading " + logFile, e);
10004                    }
10005                }
10006                if (crashInfo != null && crashInfo.stackTrace != null) {
10007                    sb.append(crashInfo.stackTrace);
10008                }
10009
10010                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10011                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10012                if (lines > 0) {
10013                    sb.append("\n");
10014
10015                    // Merge several logcat streams, and take the last N lines
10016                    InputStreamReader input = null;
10017                    try {
10018                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10019                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10020                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10021
10022                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10023                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10024                        input = new InputStreamReader(logcat.getInputStream());
10025
10026                        int num;
10027                        char[] buf = new char[8192];
10028                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10029                    } catch (IOException e) {
10030                        Slog.e(TAG, "Error running logcat", e);
10031                    } finally {
10032                        if (input != null) try { input.close(); } catch (IOException e) {}
10033                    }
10034                }
10035
10036                dbox.addText(dropboxTag, sb.toString());
10037            }
10038        };
10039
10040        if (process == null) {
10041            // If process is null, we are being called from some internal code
10042            // and may be about to die -- run this synchronously.
10043            worker.run();
10044        } else {
10045            worker.start();
10046        }
10047    }
10048
10049    /**
10050     * Bring up the "unexpected error" dialog box for a crashing app.
10051     * Deal with edge cases (intercepts from instrumented applications,
10052     * ActivityController, error intent receivers, that sort of thing).
10053     * @param r the application crashing
10054     * @param crashInfo describing the failure
10055     */
10056    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10057        long timeMillis = System.currentTimeMillis();
10058        String shortMsg = crashInfo.exceptionClassName;
10059        String longMsg = crashInfo.exceptionMessage;
10060        String stackTrace = crashInfo.stackTrace;
10061        if (shortMsg != null && longMsg != null) {
10062            longMsg = shortMsg + ": " + longMsg;
10063        } else if (shortMsg != null) {
10064            longMsg = shortMsg;
10065        }
10066
10067        AppErrorResult result = new AppErrorResult();
10068        synchronized (this) {
10069            if (mController != null) {
10070                try {
10071                    String name = r != null ? r.processName : null;
10072                    int pid = r != null ? r.pid : Binder.getCallingPid();
10073                    if (!mController.appCrashed(name, pid,
10074                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10075                        Slog.w(TAG, "Force-killing crashed app " + name
10076                                + " at watcher's request");
10077                        Process.killProcess(pid);
10078                        return;
10079                    }
10080                } catch (RemoteException e) {
10081                    mController = null;
10082                    Watchdog.getInstance().setActivityController(null);
10083                }
10084            }
10085
10086            final long origId = Binder.clearCallingIdentity();
10087
10088            // If this process is running instrumentation, finish it.
10089            if (r != null && r.instrumentationClass != null) {
10090                Slog.w(TAG, "Error in app " + r.processName
10091                      + " running instrumentation " + r.instrumentationClass + ":");
10092                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10093                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10094                Bundle info = new Bundle();
10095                info.putString("shortMsg", shortMsg);
10096                info.putString("longMsg", longMsg);
10097                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10098                Binder.restoreCallingIdentity(origId);
10099                return;
10100            }
10101
10102            // If we can't identify the process or it's already exceeded its crash quota,
10103            // quit right away without showing a crash dialog.
10104            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10105                Binder.restoreCallingIdentity(origId);
10106                return;
10107            }
10108
10109            Message msg = Message.obtain();
10110            msg.what = SHOW_ERROR_MSG;
10111            HashMap data = new HashMap();
10112            data.put("result", result);
10113            data.put("app", r);
10114            msg.obj = data;
10115            mHandler.sendMessage(msg);
10116
10117            Binder.restoreCallingIdentity(origId);
10118        }
10119
10120        int res = result.get();
10121
10122        Intent appErrorIntent = null;
10123        synchronized (this) {
10124            if (r != null && !r.isolated) {
10125                // XXX Can't keep track of crash time for isolated processes,
10126                // since they don't have a persistent identity.
10127                mProcessCrashTimes.put(r.info.processName, r.uid,
10128                        SystemClock.uptimeMillis());
10129            }
10130            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10131                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10132            }
10133        }
10134
10135        if (appErrorIntent != null) {
10136            try {
10137                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10138            } catch (ActivityNotFoundException e) {
10139                Slog.w(TAG, "bug report receiver dissappeared", e);
10140            }
10141        }
10142    }
10143
10144    Intent createAppErrorIntentLocked(ProcessRecord r,
10145            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10146        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10147        if (report == null) {
10148            return null;
10149        }
10150        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10151        result.setComponent(r.errorReportReceiver);
10152        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10153        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10154        return result;
10155    }
10156
10157    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10158            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10159        if (r.errorReportReceiver == null) {
10160            return null;
10161        }
10162
10163        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10164            return null;
10165        }
10166
10167        ApplicationErrorReport report = new ApplicationErrorReport();
10168        report.packageName = r.info.packageName;
10169        report.installerPackageName = r.errorReportReceiver.getPackageName();
10170        report.processName = r.processName;
10171        report.time = timeMillis;
10172        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10173
10174        if (r.crashing || r.forceCrashReport) {
10175            report.type = ApplicationErrorReport.TYPE_CRASH;
10176            report.crashInfo = crashInfo;
10177        } else if (r.notResponding) {
10178            report.type = ApplicationErrorReport.TYPE_ANR;
10179            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10180
10181            report.anrInfo.activity = r.notRespondingReport.tag;
10182            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10183            report.anrInfo.info = r.notRespondingReport.longMsg;
10184        }
10185
10186        return report;
10187    }
10188
10189    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10190        enforceNotIsolatedCaller("getProcessesInErrorState");
10191        // assume our apps are happy - lazy create the list
10192        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10193
10194        final boolean allUsers = ActivityManager.checkUidPermission(
10195                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10196                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10197        int userId = UserHandle.getUserId(Binder.getCallingUid());
10198
10199        synchronized (this) {
10200
10201            // iterate across all processes
10202            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10203                ProcessRecord app = mLruProcesses.get(i);
10204                if (!allUsers && app.userId != userId) {
10205                    continue;
10206                }
10207                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10208                    // This one's in trouble, so we'll generate a report for it
10209                    // crashes are higher priority (in case there's a crash *and* an anr)
10210                    ActivityManager.ProcessErrorStateInfo report = null;
10211                    if (app.crashing) {
10212                        report = app.crashingReport;
10213                    } else if (app.notResponding) {
10214                        report = app.notRespondingReport;
10215                    }
10216
10217                    if (report != null) {
10218                        if (errList == null) {
10219                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10220                        }
10221                        errList.add(report);
10222                    } else {
10223                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10224                                " crashing = " + app.crashing +
10225                                " notResponding = " + app.notResponding);
10226                    }
10227                }
10228            }
10229        }
10230
10231        return errList;
10232    }
10233
10234    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10235        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10236            if (currApp != null) {
10237                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10238            }
10239            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10240        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10241            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10242        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10243            if (currApp != null) {
10244                currApp.lru = 0;
10245            }
10246            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10247        } else if (adj >= ProcessList.SERVICE_ADJ) {
10248            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10249        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10250            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10251        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10252            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10253        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10254            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10255        } else {
10256            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10257        }
10258    }
10259
10260    private void fillInProcMemInfo(ProcessRecord app,
10261            ActivityManager.RunningAppProcessInfo outInfo) {
10262        outInfo.pid = app.pid;
10263        outInfo.uid = app.info.uid;
10264        if (mHeavyWeightProcess == app) {
10265            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10266        }
10267        if (app.persistent) {
10268            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10269        }
10270        if (app.activities.size() > 0) {
10271            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10272        }
10273        outInfo.lastTrimLevel = app.trimMemoryLevel;
10274        int adj = app.curAdj;
10275        outInfo.importance = oomAdjToImportance(adj, outInfo);
10276        outInfo.importanceReasonCode = app.adjTypeCode;
10277    }
10278
10279    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10280        enforceNotIsolatedCaller("getRunningAppProcesses");
10281        // Lazy instantiation of list
10282        List<ActivityManager.RunningAppProcessInfo> runList = null;
10283        final boolean allUsers = ActivityManager.checkUidPermission(
10284                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10285                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10286        int userId = UserHandle.getUserId(Binder.getCallingUid());
10287        synchronized (this) {
10288            // Iterate across all processes
10289            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10290                ProcessRecord app = mLruProcesses.get(i);
10291                if (!allUsers && app.userId != userId) {
10292                    continue;
10293                }
10294                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10295                    // Generate process state info for running application
10296                    ActivityManager.RunningAppProcessInfo currApp =
10297                        new ActivityManager.RunningAppProcessInfo(app.processName,
10298                                app.pid, app.getPackageList());
10299                    fillInProcMemInfo(app, currApp);
10300                    if (app.adjSource instanceof ProcessRecord) {
10301                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10302                        currApp.importanceReasonImportance = oomAdjToImportance(
10303                                app.adjSourceOom, null);
10304                    } else if (app.adjSource instanceof ActivityRecord) {
10305                        ActivityRecord r = (ActivityRecord)app.adjSource;
10306                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10307                    }
10308                    if (app.adjTarget instanceof ComponentName) {
10309                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10310                    }
10311                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10312                    //        + " lru=" + currApp.lru);
10313                    if (runList == null) {
10314                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10315                    }
10316                    runList.add(currApp);
10317                }
10318            }
10319        }
10320        return runList;
10321    }
10322
10323    public List<ApplicationInfo> getRunningExternalApplications() {
10324        enforceNotIsolatedCaller("getRunningExternalApplications");
10325        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10326        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10327        if (runningApps != null && runningApps.size() > 0) {
10328            Set<String> extList = new HashSet<String>();
10329            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10330                if (app.pkgList != null) {
10331                    for (String pkg : app.pkgList) {
10332                        extList.add(pkg);
10333                    }
10334                }
10335            }
10336            IPackageManager pm = AppGlobals.getPackageManager();
10337            for (String pkg : extList) {
10338                try {
10339                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10340                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10341                        retList.add(info);
10342                    }
10343                } catch (RemoteException e) {
10344                }
10345            }
10346        }
10347        return retList;
10348    }
10349
10350    @Override
10351    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10352        enforceNotIsolatedCaller("getMyMemoryState");
10353        synchronized (this) {
10354            ProcessRecord proc;
10355            synchronized (mPidsSelfLocked) {
10356                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10357            }
10358            fillInProcMemInfo(proc, outInfo);
10359        }
10360    }
10361
10362    @Override
10363    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10364        if (checkCallingPermission(android.Manifest.permission.DUMP)
10365                != PackageManager.PERMISSION_GRANTED) {
10366            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10367                    + Binder.getCallingPid()
10368                    + ", uid=" + Binder.getCallingUid()
10369                    + " without permission "
10370                    + android.Manifest.permission.DUMP);
10371            return;
10372        }
10373
10374        boolean dumpAll = false;
10375        boolean dumpClient = false;
10376        String dumpPackage = null;
10377
10378        int opti = 0;
10379        while (opti < args.length) {
10380            String opt = args[opti];
10381            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10382                break;
10383            }
10384            opti++;
10385            if ("-a".equals(opt)) {
10386                dumpAll = true;
10387            } else if ("-c".equals(opt)) {
10388                dumpClient = true;
10389            } else if ("-h".equals(opt)) {
10390                pw.println("Activity manager dump options:");
10391                pw.println("  [-a] [-c] [-h] [cmd] ...");
10392                pw.println("  cmd may be one of:");
10393                pw.println("    a[ctivities]: activity stack state");
10394                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10395                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10396                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10397                pw.println("    o[om]: out of memory management");
10398                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10399                pw.println("    provider [COMP_SPEC]: provider client-side state");
10400                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10401                pw.println("    service [COMP_SPEC]: service client-side state");
10402                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10403                pw.println("    all: dump all activities");
10404                pw.println("    top: dump the top activity");
10405                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10406                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10407                pw.println("    a partial substring in a component name, a");
10408                pw.println("    hex object identifier.");
10409                pw.println("  -a: include all available server state.");
10410                pw.println("  -c: include client state.");
10411                return;
10412            } else {
10413                pw.println("Unknown argument: " + opt + "; use -h for help");
10414            }
10415        }
10416
10417        long origId = Binder.clearCallingIdentity();
10418        boolean more = false;
10419        // Is the caller requesting to dump a particular piece of data?
10420        if (opti < args.length) {
10421            String cmd = args[opti];
10422            opti++;
10423            if ("activities".equals(cmd) || "a".equals(cmd)) {
10424                synchronized (this) {
10425                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10426                }
10427            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10428                String[] newArgs;
10429                String name;
10430                if (opti >= args.length) {
10431                    name = null;
10432                    newArgs = EMPTY_STRING_ARRAY;
10433                } else {
10434                    name = args[opti];
10435                    opti++;
10436                    newArgs = new String[args.length - opti];
10437                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10438                            args.length - opti);
10439                }
10440                synchronized (this) {
10441                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10442                }
10443            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10444                String[] newArgs;
10445                String name;
10446                if (opti >= args.length) {
10447                    name = null;
10448                    newArgs = EMPTY_STRING_ARRAY;
10449                } else {
10450                    name = args[opti];
10451                    opti++;
10452                    newArgs = new String[args.length - opti];
10453                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10454                            args.length - opti);
10455                }
10456                synchronized (this) {
10457                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10458                }
10459            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10460                String[] newArgs;
10461                String name;
10462                if (opti >= args.length) {
10463                    name = null;
10464                    newArgs = EMPTY_STRING_ARRAY;
10465                } else {
10466                    name = args[opti];
10467                    opti++;
10468                    newArgs = new String[args.length - opti];
10469                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10470                            args.length - opti);
10471                }
10472                synchronized (this) {
10473                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10474                }
10475            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10476                synchronized (this) {
10477                    dumpOomLocked(fd, pw, args, opti, true);
10478                }
10479            } else if ("provider".equals(cmd)) {
10480                String[] newArgs;
10481                String name;
10482                if (opti >= args.length) {
10483                    name = null;
10484                    newArgs = EMPTY_STRING_ARRAY;
10485                } else {
10486                    name = args[opti];
10487                    opti++;
10488                    newArgs = new String[args.length - opti];
10489                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10490                }
10491                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10492                    pw.println("No providers match: " + name);
10493                    pw.println("Use -h for help.");
10494                }
10495            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10496                synchronized (this) {
10497                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10498                }
10499            } else if ("service".equals(cmd)) {
10500                String[] newArgs;
10501                String name;
10502                if (opti >= args.length) {
10503                    name = null;
10504                    newArgs = EMPTY_STRING_ARRAY;
10505                } else {
10506                    name = args[opti];
10507                    opti++;
10508                    newArgs = new String[args.length - opti];
10509                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10510                            args.length - opti);
10511                }
10512                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10513                    pw.println("No services match: " + name);
10514                    pw.println("Use -h for help.");
10515                }
10516            } else if ("package".equals(cmd)) {
10517                String[] newArgs;
10518                if (opti >= args.length) {
10519                    pw.println("package: no package name specified");
10520                    pw.println("Use -h for help.");
10521                } else {
10522                    dumpPackage = args[opti];
10523                    opti++;
10524                    newArgs = new String[args.length - opti];
10525                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10526                            args.length - opti);
10527                    args = newArgs;
10528                    opti = 0;
10529                    more = true;
10530                }
10531            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10532                synchronized (this) {
10533                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10534                }
10535            } else {
10536                // Dumping a single activity?
10537                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10538                    pw.println("Bad activity command, or no activities match: " + cmd);
10539                    pw.println("Use -h for help.");
10540                }
10541            }
10542            if (!more) {
10543                Binder.restoreCallingIdentity(origId);
10544                return;
10545            }
10546        }
10547
10548        // No piece of data specified, dump everything.
10549        synchronized (this) {
10550            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10551            pw.println();
10552            if (dumpAll) {
10553                pw.println("-------------------------------------------------------------------------------");
10554            }
10555            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10556            pw.println();
10557            if (dumpAll) {
10558                pw.println("-------------------------------------------------------------------------------");
10559            }
10560            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10561            pw.println();
10562            if (dumpAll) {
10563                pw.println("-------------------------------------------------------------------------------");
10564            }
10565            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10566            pw.println();
10567            if (dumpAll) {
10568                pw.println("-------------------------------------------------------------------------------");
10569            }
10570            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10571            pw.println();
10572            if (dumpAll) {
10573                pw.println("-------------------------------------------------------------------------------");
10574            }
10575            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10576        }
10577        Binder.restoreCallingIdentity(origId);
10578    }
10579
10580    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10581            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10582        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10583
10584        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10585                dumpPackage);
10586        boolean needSep = printedAnything;
10587
10588        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10589                dumpPackage, needSep, "  mFocusedActivity: ");
10590        if (printed) {
10591            printedAnything = true;
10592            needSep = false;
10593        }
10594
10595        if (dumpPackage == null) {
10596            if (needSep) {
10597                pw.println();
10598            }
10599            needSep = true;
10600            printedAnything = true;
10601            mStackSupervisor.dump(pw, "  ");
10602        }
10603
10604        if (mRecentTasks.size() > 0) {
10605            boolean printedHeader = false;
10606
10607            final int N = mRecentTasks.size();
10608            for (int i=0; i<N; i++) {
10609                TaskRecord tr = mRecentTasks.get(i);
10610                if (dumpPackage != null) {
10611                    if (tr.realActivity == null ||
10612                            !dumpPackage.equals(tr.realActivity)) {
10613                        continue;
10614                    }
10615                }
10616                if (!printedHeader) {
10617                    if (needSep) {
10618                        pw.println();
10619                    }
10620                    pw.println("  Recent tasks:");
10621                    printedHeader = true;
10622                    printedAnything = true;
10623                }
10624                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10625                        pw.println(tr);
10626                if (dumpAll) {
10627                    mRecentTasks.get(i).dump(pw, "    ");
10628                }
10629            }
10630        }
10631
10632        if (!printedAnything) {
10633            pw.println("  (nothing)");
10634        }
10635    }
10636
10637    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10638            int opti, boolean dumpAll, String dumpPackage) {
10639        boolean needSep = false;
10640        boolean printedAnything = false;
10641        int numPers = 0;
10642
10643        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10644
10645        if (dumpAll) {
10646            final int NP = mProcessNames.getMap().size();
10647            for (int ip=0; ip<NP; ip++) {
10648                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10649                final int NA = procs.size();
10650                for (int ia=0; ia<NA; ia++) {
10651                    ProcessRecord r = procs.valueAt(ia);
10652                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10653                        continue;
10654                    }
10655                    if (!needSep) {
10656                        pw.println("  All known processes:");
10657                        needSep = true;
10658                        printedAnything = true;
10659                    }
10660                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10661                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10662                        pw.print(" "); pw.println(r);
10663                    r.dump(pw, "    ");
10664                    if (r.persistent) {
10665                        numPers++;
10666                    }
10667                }
10668            }
10669        }
10670
10671        if (mIsolatedProcesses.size() > 0) {
10672            boolean printed = false;
10673            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10674                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10675                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10676                    continue;
10677                }
10678                if (!printed) {
10679                    if (needSep) {
10680                        pw.println();
10681                    }
10682                    pw.println("  Isolated process list (sorted by uid):");
10683                    printedAnything = true;
10684                    printed = true;
10685                    needSep = true;
10686                }
10687                pw.println(String.format("%sIsolated #%2d: %s",
10688                        "    ", i, r.toString()));
10689            }
10690        }
10691
10692        if (mLruProcesses.size() > 0) {
10693            if (needSep) {
10694                pw.println();
10695            }
10696            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10697                    pw.print(" total, non-act at ");
10698                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10699                    pw.print(", non-svc at ");
10700                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10701                    pw.println("):");
10702            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10703            needSep = true;
10704            printedAnything = true;
10705        }
10706
10707        if (dumpAll || dumpPackage != null) {
10708            synchronized (mPidsSelfLocked) {
10709                boolean printed = false;
10710                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10711                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10712                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10713                        continue;
10714                    }
10715                    if (!printed) {
10716                        if (needSep) pw.println();
10717                        needSep = true;
10718                        pw.println("  PID mappings:");
10719                        printed = true;
10720                        printedAnything = true;
10721                    }
10722                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10723                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10724                }
10725            }
10726        }
10727
10728        if (mForegroundProcesses.size() > 0) {
10729            synchronized (mPidsSelfLocked) {
10730                boolean printed = false;
10731                for (int i=0; i<mForegroundProcesses.size(); i++) {
10732                    ProcessRecord r = mPidsSelfLocked.get(
10733                            mForegroundProcesses.valueAt(i).pid);
10734                    if (dumpPackage != null && (r == null
10735                            || !r.pkgList.containsKey(dumpPackage))) {
10736                        continue;
10737                    }
10738                    if (!printed) {
10739                        if (needSep) pw.println();
10740                        needSep = true;
10741                        pw.println("  Foreground Processes:");
10742                        printed = true;
10743                        printedAnything = true;
10744                    }
10745                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10746                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10747                }
10748            }
10749        }
10750
10751        if (mPersistentStartingProcesses.size() > 0) {
10752            if (needSep) pw.println();
10753            needSep = true;
10754            printedAnything = true;
10755            pw.println("  Persisent processes that are starting:");
10756            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10757                    "Starting Norm", "Restarting PERS", dumpPackage);
10758        }
10759
10760        if (mRemovedProcesses.size() > 0) {
10761            if (needSep) pw.println();
10762            needSep = true;
10763            printedAnything = true;
10764            pw.println("  Processes that are being removed:");
10765            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10766                    "Removed Norm", "Removed PERS", dumpPackage);
10767        }
10768
10769        if (mProcessesOnHold.size() > 0) {
10770            if (needSep) pw.println();
10771            needSep = true;
10772            printedAnything = true;
10773            pw.println("  Processes that are on old until the system is ready:");
10774            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10775                    "OnHold Norm", "OnHold PERS", dumpPackage);
10776        }
10777
10778        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10779
10780        if (mProcessCrashTimes.getMap().size() > 0) {
10781            boolean printed = false;
10782            long now = SystemClock.uptimeMillis();
10783            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10784            final int NP = pmap.size();
10785            for (int ip=0; ip<NP; ip++) {
10786                String pname = pmap.keyAt(ip);
10787                SparseArray<Long> uids = pmap.valueAt(ip);
10788                final int N = uids.size();
10789                for (int i=0; i<N; i++) {
10790                    int puid = uids.keyAt(i);
10791                    ProcessRecord r = mProcessNames.get(pname, puid);
10792                    if (dumpPackage != null && (r == null
10793                            || !r.pkgList.containsKey(dumpPackage))) {
10794                        continue;
10795                    }
10796                    if (!printed) {
10797                        if (needSep) pw.println();
10798                        needSep = true;
10799                        pw.println("  Time since processes crashed:");
10800                        printed = true;
10801                        printedAnything = true;
10802                    }
10803                    pw.print("    Process "); pw.print(pname);
10804                            pw.print(" uid "); pw.print(puid);
10805                            pw.print(": last crashed ");
10806                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10807                            pw.println(" ago");
10808                }
10809            }
10810        }
10811
10812        if (mBadProcesses.getMap().size() > 0) {
10813            boolean printed = false;
10814            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10815            final int NP = pmap.size();
10816            for (int ip=0; ip<NP; ip++) {
10817                String pname = pmap.keyAt(ip);
10818                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10819                final int N = uids.size();
10820                for (int i=0; i<N; i++) {
10821                    int puid = uids.keyAt(i);
10822                    ProcessRecord r = mProcessNames.get(pname, puid);
10823                    if (dumpPackage != null && (r == null
10824                            || !r.pkgList.containsKey(dumpPackage))) {
10825                        continue;
10826                    }
10827                    if (!printed) {
10828                        if (needSep) pw.println();
10829                        needSep = true;
10830                        pw.println("  Bad processes:");
10831                        printedAnything = true;
10832                    }
10833                    BadProcessInfo info = uids.valueAt(i);
10834                    pw.print("    Bad process "); pw.print(pname);
10835                            pw.print(" uid "); pw.print(puid);
10836                            pw.print(": crashed at time "); pw.println(info.time);
10837                    if (info.shortMsg != null) {
10838                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10839                    }
10840                    if (info.longMsg != null) {
10841                        pw.print("      Long msg: "); pw.println(info.longMsg);
10842                    }
10843                    if (info.stack != null) {
10844                        pw.println("      Stack:");
10845                        int lastPos = 0;
10846                        for (int pos=0; pos<info.stack.length(); pos++) {
10847                            if (info.stack.charAt(pos) == '\n') {
10848                                pw.print("        ");
10849                                pw.write(info.stack, lastPos, pos-lastPos);
10850                                pw.println();
10851                                lastPos = pos+1;
10852                            }
10853                        }
10854                        if (lastPos < info.stack.length()) {
10855                            pw.print("        ");
10856                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10857                            pw.println();
10858                        }
10859                    }
10860                }
10861            }
10862        }
10863
10864        if (dumpPackage == null) {
10865            pw.println();
10866            needSep = false;
10867            pw.println("  mStartedUsers:");
10868            for (int i=0; i<mStartedUsers.size(); i++) {
10869                UserStartedState uss = mStartedUsers.valueAt(i);
10870                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10871                        pw.print(": "); uss.dump("", pw);
10872            }
10873            pw.print("  mStartedUserArray: [");
10874            for (int i=0; i<mStartedUserArray.length; i++) {
10875                if (i > 0) pw.print(", ");
10876                pw.print(mStartedUserArray[i]);
10877            }
10878            pw.println("]");
10879            pw.print("  mUserLru: [");
10880            for (int i=0; i<mUserLru.size(); i++) {
10881                if (i > 0) pw.print(", ");
10882                pw.print(mUserLru.get(i));
10883            }
10884            pw.println("]");
10885            if (dumpAll) {
10886                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10887            }
10888        }
10889        if (mHomeProcess != null && (dumpPackage == null
10890                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10891            if (needSep) {
10892                pw.println();
10893                needSep = false;
10894            }
10895            pw.println("  mHomeProcess: " + mHomeProcess);
10896        }
10897        if (mPreviousProcess != null && (dumpPackage == null
10898                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10899            if (needSep) {
10900                pw.println();
10901                needSep = false;
10902            }
10903            pw.println("  mPreviousProcess: " + mPreviousProcess);
10904        }
10905        if (dumpAll) {
10906            StringBuilder sb = new StringBuilder(128);
10907            sb.append("  mPreviousProcessVisibleTime: ");
10908            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10909            pw.println(sb);
10910        }
10911        if (mHeavyWeightProcess != null && (dumpPackage == null
10912                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10913            if (needSep) {
10914                pw.println();
10915                needSep = false;
10916            }
10917            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10918        }
10919        if (dumpPackage == null) {
10920            pw.println("  mConfiguration: " + mConfiguration);
10921        }
10922        if (dumpAll) {
10923            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10924            if (mCompatModePackages.getPackages().size() > 0) {
10925                boolean printed = false;
10926                for (Map.Entry<String, Integer> entry
10927                        : mCompatModePackages.getPackages().entrySet()) {
10928                    String pkg = entry.getKey();
10929                    int mode = entry.getValue();
10930                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10931                        continue;
10932                    }
10933                    if (!printed) {
10934                        pw.println("  mScreenCompatPackages:");
10935                        printed = true;
10936                    }
10937                    pw.print("    "); pw.print(pkg); pw.print(": ");
10938                            pw.print(mode); pw.println();
10939                }
10940            }
10941        }
10942        if (dumpPackage == null) {
10943            if (mSleeping || mWentToSleep || mLockScreenShown) {
10944                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10945                        + " mLockScreenShown " + mLockScreenShown);
10946            }
10947            if (mShuttingDown) {
10948                pw.println("  mShuttingDown=" + mShuttingDown);
10949            }
10950        }
10951        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10952                || mOrigWaitForDebugger) {
10953            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10954                    || dumpPackage.equals(mOrigDebugApp)) {
10955                if (needSep) {
10956                    pw.println();
10957                    needSep = false;
10958                }
10959                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10960                        + " mDebugTransient=" + mDebugTransient
10961                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10962            }
10963        }
10964        if (mOpenGlTraceApp != null) {
10965            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10966                if (needSep) {
10967                    pw.println();
10968                    needSep = false;
10969                }
10970                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10971            }
10972        }
10973        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10974                || mProfileFd != null) {
10975            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10976                if (needSep) {
10977                    pw.println();
10978                    needSep = false;
10979                }
10980                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10981                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10982                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10983                        + mAutoStopProfiler);
10984            }
10985        }
10986        if (dumpPackage == null) {
10987            if (mAlwaysFinishActivities || mController != null) {
10988                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10989                        + " mController=" + mController);
10990            }
10991            if (dumpAll) {
10992                pw.println("  Total persistent processes: " + numPers);
10993                pw.println("  mStartRunning=" + mStartRunning
10994                        + " mProcessesReady=" + mProcessesReady
10995                        + " mSystemReady=" + mSystemReady);
10996                pw.println("  mBooting=" + mBooting
10997                        + " mBooted=" + mBooted
10998                        + " mFactoryTest=" + mFactoryTest);
10999                pw.print("  mLastPowerCheckRealtime=");
11000                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11001                        pw.println("");
11002                pw.print("  mLastPowerCheckUptime=");
11003                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11004                        pw.println("");
11005                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11006                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11007                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11008                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11009                        + " (" + mLruProcesses.size() + " total)"
11010                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11011                        + " mNumServiceProcs=" + mNumServiceProcs
11012                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11013                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11014                        + " mLastMemoryLevel" + mLastMemoryLevel
11015                        + " mLastNumProcesses" + mLastNumProcesses);
11016                long now = SystemClock.uptimeMillis();
11017                pw.print("  mLastIdleTime=");
11018                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11019                        pw.print(" mLowRamSinceLastIdle=");
11020                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11021                        pw.println();
11022            }
11023        }
11024
11025        if (!printedAnything) {
11026            pw.println("  (nothing)");
11027        }
11028    }
11029
11030    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11031            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11032        if (mProcessesToGc.size() > 0) {
11033            boolean printed = false;
11034            long now = SystemClock.uptimeMillis();
11035            for (int i=0; i<mProcessesToGc.size(); i++) {
11036                ProcessRecord proc = mProcessesToGc.get(i);
11037                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11038                    continue;
11039                }
11040                if (!printed) {
11041                    if (needSep) pw.println();
11042                    needSep = true;
11043                    pw.println("  Processes that are waiting to GC:");
11044                    printed = true;
11045                }
11046                pw.print("    Process "); pw.println(proc);
11047                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11048                        pw.print(", last gced=");
11049                        pw.print(now-proc.lastRequestedGc);
11050                        pw.print(" ms ago, last lowMem=");
11051                        pw.print(now-proc.lastLowMemory);
11052                        pw.println(" ms ago");
11053
11054            }
11055        }
11056        return needSep;
11057    }
11058
11059    void printOomLevel(PrintWriter pw, String name, int adj) {
11060        pw.print("    ");
11061        if (adj >= 0) {
11062            pw.print(' ');
11063            if (adj < 10) pw.print(' ');
11064        } else {
11065            if (adj > -10) pw.print(' ');
11066        }
11067        pw.print(adj);
11068        pw.print(": ");
11069        pw.print(name);
11070        pw.print(" (");
11071        pw.print(mProcessList.getMemLevel(adj)/1024);
11072        pw.println(" kB)");
11073    }
11074
11075    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11076            int opti, boolean dumpAll) {
11077        boolean needSep = false;
11078
11079        if (mLruProcesses.size() > 0) {
11080            if (needSep) pw.println();
11081            needSep = true;
11082            pw.println("  OOM levels:");
11083            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11084            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11085            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11086            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11087            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11088            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11089            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11090            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11091            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11092            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11093            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11094            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11095            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11096
11097            if (needSep) pw.println();
11098            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11099                    pw.print(" total, non-act at ");
11100                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11101                    pw.print(", non-svc at ");
11102                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11103                    pw.println("):");
11104            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11105            needSep = true;
11106        }
11107
11108        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11109
11110        pw.println();
11111        pw.println("  mHomeProcess: " + mHomeProcess);
11112        pw.println("  mPreviousProcess: " + mPreviousProcess);
11113        if (mHeavyWeightProcess != null) {
11114            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11115        }
11116
11117        return true;
11118    }
11119
11120    /**
11121     * There are three ways to call this:
11122     *  - no provider specified: dump all the providers
11123     *  - a flattened component name that matched an existing provider was specified as the
11124     *    first arg: dump that one provider
11125     *  - the first arg isn't the flattened component name of an existing provider:
11126     *    dump all providers whose component contains the first arg as a substring
11127     */
11128    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11129            int opti, boolean dumpAll) {
11130        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11131    }
11132
11133    static class ItemMatcher {
11134        ArrayList<ComponentName> components;
11135        ArrayList<String> strings;
11136        ArrayList<Integer> objects;
11137        boolean all;
11138
11139        ItemMatcher() {
11140            all = true;
11141        }
11142
11143        void build(String name) {
11144            ComponentName componentName = ComponentName.unflattenFromString(name);
11145            if (componentName != null) {
11146                if (components == null) {
11147                    components = new ArrayList<ComponentName>();
11148                }
11149                components.add(componentName);
11150                all = false;
11151            } else {
11152                int objectId = 0;
11153                // Not a '/' separated full component name; maybe an object ID?
11154                try {
11155                    objectId = Integer.parseInt(name, 16);
11156                    if (objects == null) {
11157                        objects = new ArrayList<Integer>();
11158                    }
11159                    objects.add(objectId);
11160                    all = false;
11161                } catch (RuntimeException e) {
11162                    // Not an integer; just do string match.
11163                    if (strings == null) {
11164                        strings = new ArrayList<String>();
11165                    }
11166                    strings.add(name);
11167                    all = false;
11168                }
11169            }
11170        }
11171
11172        int build(String[] args, int opti) {
11173            for (; opti<args.length; opti++) {
11174                String name = args[opti];
11175                if ("--".equals(name)) {
11176                    return opti+1;
11177                }
11178                build(name);
11179            }
11180            return opti;
11181        }
11182
11183        boolean match(Object object, ComponentName comp) {
11184            if (all) {
11185                return true;
11186            }
11187            if (components != null) {
11188                for (int i=0; i<components.size(); i++) {
11189                    if (components.get(i).equals(comp)) {
11190                        return true;
11191                    }
11192                }
11193            }
11194            if (objects != null) {
11195                for (int i=0; i<objects.size(); i++) {
11196                    if (System.identityHashCode(object) == objects.get(i)) {
11197                        return true;
11198                    }
11199                }
11200            }
11201            if (strings != null) {
11202                String flat = comp.flattenToString();
11203                for (int i=0; i<strings.size(); i++) {
11204                    if (flat.contains(strings.get(i))) {
11205                        return true;
11206                    }
11207                }
11208            }
11209            return false;
11210        }
11211    }
11212
11213    /**
11214     * There are three things that cmd can be:
11215     *  - a flattened component name that matches an existing activity
11216     *  - the cmd arg isn't the flattened component name of an existing activity:
11217     *    dump all activity whose component contains the cmd as a substring
11218     *  - A hex number of the ActivityRecord object instance.
11219     */
11220    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11221            int opti, boolean dumpAll) {
11222        ArrayList<ActivityRecord> activities;
11223
11224        synchronized (this) {
11225            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11226        }
11227
11228        if (activities.size() <= 0) {
11229            return false;
11230        }
11231
11232        String[] newArgs = new String[args.length - opti];
11233        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11234
11235        TaskRecord lastTask = null;
11236        boolean needSep = false;
11237        for (int i=activities.size()-1; i>=0; i--) {
11238            ActivityRecord r = activities.get(i);
11239            if (needSep) {
11240                pw.println();
11241            }
11242            needSep = true;
11243            synchronized (this) {
11244                if (lastTask != r.task) {
11245                    lastTask = r.task;
11246                    pw.print("TASK "); pw.print(lastTask.affinity);
11247                            pw.print(" id="); pw.println(lastTask.taskId);
11248                    if (dumpAll) {
11249                        lastTask.dump(pw, "  ");
11250                    }
11251                }
11252            }
11253            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11254        }
11255        return true;
11256    }
11257
11258    /**
11259     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11260     * there is a thread associated with the activity.
11261     */
11262    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11263            final ActivityRecord r, String[] args, boolean dumpAll) {
11264        String innerPrefix = prefix + "  ";
11265        synchronized (this) {
11266            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11267                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11268                    pw.print(" pid=");
11269                    if (r.app != null) pw.println(r.app.pid);
11270                    else pw.println("(not running)");
11271            if (dumpAll) {
11272                r.dump(pw, innerPrefix);
11273            }
11274        }
11275        if (r.app != null && r.app.thread != null) {
11276            // flush anything that is already in the PrintWriter since the thread is going
11277            // to write to the file descriptor directly
11278            pw.flush();
11279            try {
11280                TransferPipe tp = new TransferPipe();
11281                try {
11282                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11283                            r.appToken, innerPrefix, args);
11284                    tp.go(fd);
11285                } finally {
11286                    tp.kill();
11287                }
11288            } catch (IOException e) {
11289                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11290            } catch (RemoteException e) {
11291                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11292            }
11293        }
11294    }
11295
11296    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11297            int opti, boolean dumpAll, String dumpPackage) {
11298        boolean needSep = false;
11299        boolean onlyHistory = false;
11300        boolean printedAnything = false;
11301
11302        if ("history".equals(dumpPackage)) {
11303            if (opti < args.length && "-s".equals(args[opti])) {
11304                dumpAll = false;
11305            }
11306            onlyHistory = true;
11307            dumpPackage = null;
11308        }
11309
11310        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11311        if (!onlyHistory && dumpAll) {
11312            if (mRegisteredReceivers.size() > 0) {
11313                boolean printed = false;
11314                Iterator it = mRegisteredReceivers.values().iterator();
11315                while (it.hasNext()) {
11316                    ReceiverList r = (ReceiverList)it.next();
11317                    if (dumpPackage != null && (r.app == null ||
11318                            !dumpPackage.equals(r.app.info.packageName))) {
11319                        continue;
11320                    }
11321                    if (!printed) {
11322                        pw.println("  Registered Receivers:");
11323                        needSep = true;
11324                        printed = true;
11325                        printedAnything = true;
11326                    }
11327                    pw.print("  * "); pw.println(r);
11328                    r.dump(pw, "    ");
11329                }
11330            }
11331
11332            if (mReceiverResolver.dump(pw, needSep ?
11333                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11334                    "    ", dumpPackage, false)) {
11335                needSep = true;
11336                printedAnything = true;
11337            }
11338        }
11339
11340        for (BroadcastQueue q : mBroadcastQueues) {
11341            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11342            printedAnything |= needSep;
11343        }
11344
11345        needSep = true;
11346
11347        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11348            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11349                if (needSep) {
11350                    pw.println();
11351                }
11352                needSep = true;
11353                printedAnything = true;
11354                pw.print("  Sticky broadcasts for user ");
11355                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11356                StringBuilder sb = new StringBuilder(128);
11357                for (Map.Entry<String, ArrayList<Intent>> ent
11358                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11359                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11360                    if (dumpAll) {
11361                        pw.println(":");
11362                        ArrayList<Intent> intents = ent.getValue();
11363                        final int N = intents.size();
11364                        for (int i=0; i<N; i++) {
11365                            sb.setLength(0);
11366                            sb.append("    Intent: ");
11367                            intents.get(i).toShortString(sb, false, true, false, false);
11368                            pw.println(sb.toString());
11369                            Bundle bundle = intents.get(i).getExtras();
11370                            if (bundle != null) {
11371                                pw.print("      ");
11372                                pw.println(bundle.toString());
11373                            }
11374                        }
11375                    } else {
11376                        pw.println("");
11377                    }
11378                }
11379            }
11380        }
11381
11382        if (!onlyHistory && dumpAll) {
11383            pw.println();
11384            for (BroadcastQueue queue : mBroadcastQueues) {
11385                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11386                        + queue.mBroadcastsScheduled);
11387            }
11388            pw.println("  mHandler:");
11389            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11390            needSep = true;
11391            printedAnything = true;
11392        }
11393
11394        if (!printedAnything) {
11395            pw.println("  (nothing)");
11396        }
11397    }
11398
11399    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11400            int opti, boolean dumpAll, String dumpPackage) {
11401        boolean needSep;
11402        boolean printedAnything = false;
11403
11404        ItemMatcher matcher = new ItemMatcher();
11405        matcher.build(args, opti);
11406
11407        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11408
11409        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11410        printedAnything |= needSep;
11411
11412        if (mLaunchingProviders.size() > 0) {
11413            boolean printed = false;
11414            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11415                ContentProviderRecord r = mLaunchingProviders.get(i);
11416                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11417                    continue;
11418                }
11419                if (!printed) {
11420                    if (needSep) pw.println();
11421                    needSep = true;
11422                    pw.println("  Launching content providers:");
11423                    printed = true;
11424                    printedAnything = true;
11425                }
11426                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11427                        pw.println(r);
11428            }
11429        }
11430
11431        if (mGrantedUriPermissions.size() > 0) {
11432            boolean printed = false;
11433            int dumpUid = -2;
11434            if (dumpPackage != null) {
11435                try {
11436                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11437                } catch (NameNotFoundException e) {
11438                    dumpUid = -1;
11439                }
11440            }
11441            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11442                int uid = mGrantedUriPermissions.keyAt(i);
11443                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11444                    continue;
11445                }
11446                ArrayMap<Uri, UriPermission> perms
11447                        = mGrantedUriPermissions.valueAt(i);
11448                if (!printed) {
11449                    if (needSep) pw.println();
11450                    needSep = true;
11451                    pw.println("  Granted Uri Permissions:");
11452                    printed = true;
11453                    printedAnything = true;
11454                }
11455                pw.print("  * UID "); pw.print(uid);
11456                        pw.println(" holds:");
11457                for (UriPermission perm : perms.values()) {
11458                    pw.print("    "); pw.println(perm);
11459                    if (dumpAll) {
11460                        perm.dump(pw, "      ");
11461                    }
11462                }
11463            }
11464        }
11465
11466        if (!printedAnything) {
11467            pw.println("  (nothing)");
11468        }
11469    }
11470
11471    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11472            int opti, boolean dumpAll, String dumpPackage) {
11473        boolean printed = false;
11474
11475        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11476
11477        if (mIntentSenderRecords.size() > 0) {
11478            Iterator<WeakReference<PendingIntentRecord>> it
11479                    = mIntentSenderRecords.values().iterator();
11480            while (it.hasNext()) {
11481                WeakReference<PendingIntentRecord> ref = it.next();
11482                PendingIntentRecord rec = ref != null ? ref.get(): null;
11483                if (dumpPackage != null && (rec == null
11484                        || !dumpPackage.equals(rec.key.packageName))) {
11485                    continue;
11486                }
11487                printed = true;
11488                if (rec != null) {
11489                    pw.print("  * "); pw.println(rec);
11490                    if (dumpAll) {
11491                        rec.dump(pw, "    ");
11492                    }
11493                } else {
11494                    pw.print("  * "); pw.println(ref);
11495                }
11496            }
11497        }
11498
11499        if (!printed) {
11500            pw.println("  (nothing)");
11501        }
11502    }
11503
11504    private static final int dumpProcessList(PrintWriter pw,
11505            ActivityManagerService service, List list,
11506            String prefix, String normalLabel, String persistentLabel,
11507            String dumpPackage) {
11508        int numPers = 0;
11509        final int N = list.size()-1;
11510        for (int i=N; i>=0; i--) {
11511            ProcessRecord r = (ProcessRecord)list.get(i);
11512            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11513                continue;
11514            }
11515            pw.println(String.format("%s%s #%2d: %s",
11516                    prefix, (r.persistent ? persistentLabel : normalLabel),
11517                    i, r.toString()));
11518            if (r.persistent) {
11519                numPers++;
11520            }
11521        }
11522        return numPers;
11523    }
11524
11525    private static final boolean dumpProcessOomList(PrintWriter pw,
11526            ActivityManagerService service, List<ProcessRecord> origList,
11527            String prefix, String normalLabel, String persistentLabel,
11528            boolean inclDetails, String dumpPackage) {
11529
11530        ArrayList<Pair<ProcessRecord, Integer>> list
11531                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11532        for (int i=0; i<origList.size(); i++) {
11533            ProcessRecord r = origList.get(i);
11534            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11535                continue;
11536            }
11537            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11538        }
11539
11540        if (list.size() <= 0) {
11541            return false;
11542        }
11543
11544        Comparator<Pair<ProcessRecord, Integer>> comparator
11545                = new Comparator<Pair<ProcessRecord, Integer>>() {
11546            @Override
11547            public int compare(Pair<ProcessRecord, Integer> object1,
11548                    Pair<ProcessRecord, Integer> object2) {
11549                if (object1.first.setAdj != object2.first.setAdj) {
11550                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11551                }
11552                if (object1.second.intValue() != object2.second.intValue()) {
11553                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11554                }
11555                return 0;
11556            }
11557        };
11558
11559        Collections.sort(list, comparator);
11560
11561        final long curRealtime = SystemClock.elapsedRealtime();
11562        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11563        final long curUptime = SystemClock.uptimeMillis();
11564        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11565
11566        for (int i=list.size()-1; i>=0; i--) {
11567            ProcessRecord r = list.get(i).first;
11568            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11569            char schedGroup;
11570            switch (r.setSchedGroup) {
11571                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11572                    schedGroup = 'B';
11573                    break;
11574                case Process.THREAD_GROUP_DEFAULT:
11575                    schedGroup = 'F';
11576                    break;
11577                default:
11578                    schedGroup = '?';
11579                    break;
11580            }
11581            char foreground;
11582            if (r.foregroundActivities) {
11583                foreground = 'A';
11584            } else if (r.foregroundServices) {
11585                foreground = 'S';
11586            } else {
11587                foreground = ' ';
11588            }
11589            String procState = ProcessList.makeProcStateString(r.curProcState);
11590            pw.print(prefix);
11591            pw.print(r.persistent ? persistentLabel : normalLabel);
11592            pw.print(" #");
11593            int num = (origList.size()-1)-list.get(i).second;
11594            if (num < 10) pw.print(' ');
11595            pw.print(num);
11596            pw.print(": ");
11597            pw.print(oomAdj);
11598            pw.print(' ');
11599            pw.print(schedGroup);
11600            pw.print('/');
11601            pw.print(foreground);
11602            pw.print('/');
11603            pw.print(procState);
11604            pw.print(" trm:");
11605            if (r.trimMemoryLevel < 10) pw.print(' ');
11606            pw.print(r.trimMemoryLevel);
11607            pw.print(' ');
11608            pw.print(r.toShortString());
11609            pw.print(" (");
11610            pw.print(r.adjType);
11611            pw.println(')');
11612            if (r.adjSource != null || r.adjTarget != null) {
11613                pw.print(prefix);
11614                pw.print("    ");
11615                if (r.adjTarget instanceof ComponentName) {
11616                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11617                } else if (r.adjTarget != null) {
11618                    pw.print(r.adjTarget.toString());
11619                } else {
11620                    pw.print("{null}");
11621                }
11622                pw.print("<=");
11623                if (r.adjSource instanceof ProcessRecord) {
11624                    pw.print("Proc{");
11625                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11626                    pw.println("}");
11627                } else if (r.adjSource != null) {
11628                    pw.println(r.adjSource.toString());
11629                } else {
11630                    pw.println("{null}");
11631                }
11632            }
11633            if (inclDetails) {
11634                pw.print(prefix);
11635                pw.print("    ");
11636                pw.print("oom: max="); pw.print(r.maxAdj);
11637                pw.print(" curRaw="); pw.print(r.curRawAdj);
11638                pw.print(" setRaw="); pw.print(r.setRawAdj);
11639                pw.print(" cur="); pw.print(r.curAdj);
11640                pw.print(" set="); pw.println(r.setAdj);
11641                pw.print(prefix);
11642                pw.print("    ");
11643                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11644                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11645                pw.print(" lastPss="); pw.print(r.lastPss);
11646                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11647                pw.print(prefix);
11648                pw.print("    ");
11649                pw.print("keeping="); pw.print(r.keeping);
11650                pw.print(" cached="); pw.print(r.cached);
11651                pw.print(" empty="); pw.print(r.empty);
11652                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11653
11654                if (!r.keeping) {
11655                    if (r.lastWakeTime != 0) {
11656                        long wtime;
11657                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11658                        synchronized (stats) {
11659                            wtime = stats.getProcessWakeTime(r.info.uid,
11660                                    r.pid, curRealtime);
11661                        }
11662                        long timeUsed = wtime - r.lastWakeTime;
11663                        pw.print(prefix);
11664                        pw.print("    ");
11665                        pw.print("keep awake over ");
11666                        TimeUtils.formatDuration(realtimeSince, pw);
11667                        pw.print(" used ");
11668                        TimeUtils.formatDuration(timeUsed, pw);
11669                        pw.print(" (");
11670                        pw.print((timeUsed*100)/realtimeSince);
11671                        pw.println("%)");
11672                    }
11673                    if (r.lastCpuTime != 0) {
11674                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11675                        pw.print(prefix);
11676                        pw.print("    ");
11677                        pw.print("run cpu over ");
11678                        TimeUtils.formatDuration(uptimeSince, pw);
11679                        pw.print(" used ");
11680                        TimeUtils.formatDuration(timeUsed, pw);
11681                        pw.print(" (");
11682                        pw.print((timeUsed*100)/uptimeSince);
11683                        pw.println("%)");
11684                    }
11685                }
11686            }
11687        }
11688        return true;
11689    }
11690
11691    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11692        ArrayList<ProcessRecord> procs;
11693        synchronized (this) {
11694            if (args != null && args.length > start
11695                    && args[start].charAt(0) != '-') {
11696                procs = new ArrayList<ProcessRecord>();
11697                int pid = -1;
11698                try {
11699                    pid = Integer.parseInt(args[start]);
11700                } catch (NumberFormatException e) {
11701                }
11702                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11703                    ProcessRecord proc = mLruProcesses.get(i);
11704                    if (proc.pid == pid) {
11705                        procs.add(proc);
11706                    } else if (proc.processName.equals(args[start])) {
11707                        procs.add(proc);
11708                    }
11709                }
11710                if (procs.size() <= 0) {
11711                    return null;
11712                }
11713            } else {
11714                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11715            }
11716        }
11717        return procs;
11718    }
11719
11720    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11721            PrintWriter pw, String[] args) {
11722        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11723        if (procs == null) {
11724            pw.println("No process found for: " + args[0]);
11725            return;
11726        }
11727
11728        long uptime = SystemClock.uptimeMillis();
11729        long realtime = SystemClock.elapsedRealtime();
11730        pw.println("Applications Graphics Acceleration Info:");
11731        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11732
11733        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11734            ProcessRecord r = procs.get(i);
11735            if (r.thread != null) {
11736                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11737                pw.flush();
11738                try {
11739                    TransferPipe tp = new TransferPipe();
11740                    try {
11741                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11742                        tp.go(fd);
11743                    } finally {
11744                        tp.kill();
11745                    }
11746                } catch (IOException e) {
11747                    pw.println("Failure while dumping the app: " + r);
11748                    pw.flush();
11749                } catch (RemoteException e) {
11750                    pw.println("Got a RemoteException while dumping the app " + r);
11751                    pw.flush();
11752                }
11753            }
11754        }
11755    }
11756
11757    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11758        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11759        if (procs == null) {
11760            pw.println("No process found for: " + args[0]);
11761            return;
11762        }
11763
11764        pw.println("Applications Database Info:");
11765
11766        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11767            ProcessRecord r = procs.get(i);
11768            if (r.thread != null) {
11769                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11770                pw.flush();
11771                try {
11772                    TransferPipe tp = new TransferPipe();
11773                    try {
11774                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11775                        tp.go(fd);
11776                    } finally {
11777                        tp.kill();
11778                    }
11779                } catch (IOException e) {
11780                    pw.println("Failure while dumping the app: " + r);
11781                    pw.flush();
11782                } catch (RemoteException e) {
11783                    pw.println("Got a RemoteException while dumping the app " + r);
11784                    pw.flush();
11785                }
11786            }
11787        }
11788    }
11789
11790    final static class MemItem {
11791        final boolean isProc;
11792        final String label;
11793        final String shortLabel;
11794        final long pss;
11795        final int id;
11796        final boolean hasActivities;
11797        ArrayList<MemItem> subitems;
11798
11799        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11800                boolean _hasActivities) {
11801            isProc = true;
11802            label = _label;
11803            shortLabel = _shortLabel;
11804            pss = _pss;
11805            id = _id;
11806            hasActivities = _hasActivities;
11807        }
11808
11809        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11810            isProc = false;
11811            label = _label;
11812            shortLabel = _shortLabel;
11813            pss = _pss;
11814            id = _id;
11815            hasActivities = false;
11816        }
11817    }
11818
11819    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11820            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11821        if (sort && !isCompact) {
11822            Collections.sort(items, new Comparator<MemItem>() {
11823                @Override
11824                public int compare(MemItem lhs, MemItem rhs) {
11825                    if (lhs.pss < rhs.pss) {
11826                        return 1;
11827                    } else if (lhs.pss > rhs.pss) {
11828                        return -1;
11829                    }
11830                    return 0;
11831                }
11832            });
11833        }
11834
11835        for (int i=0; i<items.size(); i++) {
11836            MemItem mi = items.get(i);
11837            if (!isCompact) {
11838                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11839            } else if (mi.isProc) {
11840                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11841                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11842                pw.println(mi.hasActivities ? ",a" : ",e");
11843            } else {
11844                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11845                pw.println(mi.pss);
11846            }
11847            if (mi.subitems != null) {
11848                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11849                        true, isCompact);
11850            }
11851        }
11852    }
11853
11854    // These are in KB.
11855    static final long[] DUMP_MEM_BUCKETS = new long[] {
11856        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11857        120*1024, 160*1024, 200*1024,
11858        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11859        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11860    };
11861
11862    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11863            boolean stackLike) {
11864        int start = label.lastIndexOf('.');
11865        if (start >= 0) start++;
11866        else start = 0;
11867        int end = label.length();
11868        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11869            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11870                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11871                out.append(bucket);
11872                out.append(stackLike ? "MB." : "MB ");
11873                out.append(label, start, end);
11874                return;
11875            }
11876        }
11877        out.append(memKB/1024);
11878        out.append(stackLike ? "MB." : "MB ");
11879        out.append(label, start, end);
11880    }
11881
11882    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11883            ProcessList.NATIVE_ADJ,
11884            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11885            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11886            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11887            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11888            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11889    };
11890    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11891            "Native",
11892            "System", "Persistent", "Foreground",
11893            "Visible", "Perceptible",
11894            "Heavy Weight", "Backup",
11895            "A Services", "Home",
11896            "Previous", "B Services", "Cached"
11897    };
11898    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11899            "native",
11900            "sys", "pers", "fore",
11901            "vis", "percept",
11902            "heavy", "backup",
11903            "servicea", "home",
11904            "prev", "serviceb", "cached"
11905    };
11906
11907    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11908            long realtime, boolean isCheckinRequest, boolean isCompact) {
11909        if (isCheckinRequest || isCompact) {
11910            // short checkin version
11911            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11912        } else {
11913            pw.println("Applications Memory Usage (kB):");
11914            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11915        }
11916    }
11917
11918    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11919            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11920        boolean dumpDetails = false;
11921        boolean dumpFullDetails = false;
11922        boolean dumpDalvik = false;
11923        boolean oomOnly = false;
11924        boolean isCompact = false;
11925        boolean localOnly = false;
11926
11927        int opti = 0;
11928        while (opti < args.length) {
11929            String opt = args[opti];
11930            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11931                break;
11932            }
11933            opti++;
11934            if ("-a".equals(opt)) {
11935                dumpDetails = true;
11936                dumpFullDetails = true;
11937                dumpDalvik = true;
11938            } else if ("-d".equals(opt)) {
11939                dumpDalvik = true;
11940            } else if ("-c".equals(opt)) {
11941                isCompact = true;
11942            } else if ("--oom".equals(opt)) {
11943                oomOnly = true;
11944            } else if ("--local".equals(opt)) {
11945                localOnly = true;
11946            } else if ("-h".equals(opt)) {
11947                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11948                pw.println("  -a: include all available information for each process.");
11949                pw.println("  -d: include dalvik details when dumping process details.");
11950                pw.println("  -c: dump in a compact machine-parseable representation.");
11951                pw.println("  --oom: only show processes organized by oom adj.");
11952                pw.println("  --local: only collect details locally, don't call process.");
11953                pw.println("If [process] is specified it can be the name or ");
11954                pw.println("pid of a specific process to dump.");
11955                return;
11956            } else {
11957                pw.println("Unknown argument: " + opt + "; use -h for help");
11958            }
11959        }
11960
11961        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11962        long uptime = SystemClock.uptimeMillis();
11963        long realtime = SystemClock.elapsedRealtime();
11964        final long[] tmpLong = new long[1];
11965
11966        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11967        if (procs == null) {
11968            // No Java processes.  Maybe they want to print a native process.
11969            if (args != null && args.length > opti
11970                    && args[opti].charAt(0) != '-') {
11971                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11972                        = new ArrayList<ProcessCpuTracker.Stats>();
11973                updateCpuStatsNow();
11974                int findPid = -1;
11975                try {
11976                    findPid = Integer.parseInt(args[opti]);
11977                } catch (NumberFormatException e) {
11978                }
11979                synchronized (mProcessCpuThread) {
11980                    final int N = mProcessCpuTracker.countStats();
11981                    for (int i=0; i<N; i++) {
11982                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11983                        if (st.pid == findPid || (st.baseName != null
11984                                && st.baseName.equals(args[opti]))) {
11985                            nativeProcs.add(st);
11986                        }
11987                    }
11988                }
11989                if (nativeProcs.size() > 0) {
11990                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11991                            isCompact);
11992                    Debug.MemoryInfo mi = null;
11993                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11994                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11995                        final int pid = r.pid;
11996                        if (!isCheckinRequest && dumpDetails) {
11997                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11998                        }
11999                        if (mi == null) {
12000                            mi = new Debug.MemoryInfo();
12001                        }
12002                        if (dumpDetails || (!brief && !oomOnly)) {
12003                            Debug.getMemoryInfo(pid, mi);
12004                        } else {
12005                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12006                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12007                        }
12008                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12009                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12010                        if (isCheckinRequest) {
12011                            pw.println();
12012                        }
12013                    }
12014                    return;
12015                }
12016            }
12017            pw.println("No process found for: " + args[opti]);
12018            return;
12019        }
12020
12021        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12022            dumpDetails = true;
12023        }
12024
12025        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12026
12027        String[] innerArgs = new String[args.length-opti];
12028        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12029
12030        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12031        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12032        long nativePss=0, dalvikPss=0, otherPss=0;
12033        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12034
12035        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12036        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12037                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12038
12039        long totalPss = 0;
12040        long cachedPss = 0;
12041
12042        Debug.MemoryInfo mi = null;
12043        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12044            final ProcessRecord r = procs.get(i);
12045            final IApplicationThread thread;
12046            final int pid;
12047            final int oomAdj;
12048            final boolean hasActivities;
12049            synchronized (this) {
12050                thread = r.thread;
12051                pid = r.pid;
12052                oomAdj = r.getSetAdjWithServices();
12053                hasActivities = r.activities.size() > 0;
12054            }
12055            if (thread != null) {
12056                if (!isCheckinRequest && dumpDetails) {
12057                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12058                }
12059                if (mi == null) {
12060                    mi = new Debug.MemoryInfo();
12061                }
12062                if (dumpDetails || (!brief && !oomOnly)) {
12063                    Debug.getMemoryInfo(pid, mi);
12064                } else {
12065                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12066                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12067                }
12068                if (dumpDetails) {
12069                    if (localOnly) {
12070                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12071                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12072                        if (isCheckinRequest) {
12073                            pw.println();
12074                        }
12075                    } else {
12076                        try {
12077                            pw.flush();
12078                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12079                                    dumpDalvik, innerArgs);
12080                        } catch (RemoteException e) {
12081                            if (!isCheckinRequest) {
12082                                pw.println("Got RemoteException!");
12083                                pw.flush();
12084                            }
12085                        }
12086                    }
12087                }
12088
12089                final long myTotalPss = mi.getTotalPss();
12090                final long myTotalUss = mi.getTotalUss();
12091
12092                synchronized (this) {
12093                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12094                        // Record this for posterity if the process has been stable.
12095                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12096                    }
12097                }
12098
12099                if (!isCheckinRequest && mi != null) {
12100                    totalPss += myTotalPss;
12101                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12102                            (hasActivities ? " / activities)" : ")"),
12103                            r.processName, myTotalPss, pid, hasActivities);
12104                    procMems.add(pssItem);
12105                    procMemsMap.put(pid, pssItem);
12106
12107                    nativePss += mi.nativePss;
12108                    dalvikPss += mi.dalvikPss;
12109                    otherPss += mi.otherPss;
12110                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12111                        long mem = mi.getOtherPss(j);
12112                        miscPss[j] += mem;
12113                        otherPss -= mem;
12114                    }
12115
12116                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12117                        cachedPss += myTotalPss;
12118                    }
12119
12120                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12121                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12122                                || oomIndex == (oomPss.length-1)) {
12123                            oomPss[oomIndex] += myTotalPss;
12124                            if (oomProcs[oomIndex] == null) {
12125                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12126                            }
12127                            oomProcs[oomIndex].add(pssItem);
12128                            break;
12129                        }
12130                    }
12131                }
12132            }
12133        }
12134
12135        if (!isCheckinRequest && procs.size() > 1) {
12136            // If we are showing aggregations, also look for native processes to
12137            // include so that our aggregations are more accurate.
12138            updateCpuStatsNow();
12139            synchronized (mProcessCpuThread) {
12140                final int N = mProcessCpuTracker.countStats();
12141                for (int i=0; i<N; i++) {
12142                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12143                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12144                        if (mi == null) {
12145                            mi = new Debug.MemoryInfo();
12146                        }
12147                        if (!brief && !oomOnly) {
12148                            Debug.getMemoryInfo(st.pid, mi);
12149                        } else {
12150                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12151                            mi.nativePrivateDirty = (int)tmpLong[0];
12152                        }
12153
12154                        final long myTotalPss = mi.getTotalPss();
12155                        totalPss += myTotalPss;
12156
12157                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12158                                st.name, myTotalPss, st.pid, false);
12159                        procMems.add(pssItem);
12160
12161                        nativePss += mi.nativePss;
12162                        dalvikPss += mi.dalvikPss;
12163                        otherPss += mi.otherPss;
12164                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12165                            long mem = mi.getOtherPss(j);
12166                            miscPss[j] += mem;
12167                            otherPss -= mem;
12168                        }
12169                        oomPss[0] += myTotalPss;
12170                        if (oomProcs[0] == null) {
12171                            oomProcs[0] = new ArrayList<MemItem>();
12172                        }
12173                        oomProcs[0].add(pssItem);
12174                    }
12175                }
12176            }
12177
12178            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12179
12180            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12181            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12182            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12183            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12184                String label = Debug.MemoryInfo.getOtherLabel(j);
12185                catMems.add(new MemItem(label, label, miscPss[j], j));
12186            }
12187
12188            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12189            for (int j=0; j<oomPss.length; j++) {
12190                if (oomPss[j] != 0) {
12191                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12192                            : DUMP_MEM_OOM_LABEL[j];
12193                    MemItem item = new MemItem(label, label, oomPss[j],
12194                            DUMP_MEM_OOM_ADJ[j]);
12195                    item.subitems = oomProcs[j];
12196                    oomMems.add(item);
12197                }
12198            }
12199
12200            if (!brief && !oomOnly && !isCompact) {
12201                pw.println();
12202                pw.println("Total PSS by process:");
12203                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12204                pw.println();
12205            }
12206            if (!isCompact) {
12207                pw.println("Total PSS by OOM adjustment:");
12208            }
12209            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12210            if (!brief && !oomOnly) {
12211                PrintWriter out = categoryPw != null ? categoryPw : pw;
12212                if (!isCompact) {
12213                    out.println();
12214                    out.println("Total PSS by category:");
12215                }
12216                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12217            }
12218            if (!isCompact) {
12219                pw.println();
12220            }
12221            MemInfoReader memInfo = new MemInfoReader();
12222            memInfo.readMemInfo();
12223            if (!brief) {
12224                if (!isCompact) {
12225                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12226                    pw.print(" kB (status ");
12227                    switch (mLastMemoryLevel) {
12228                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12229                            pw.println("normal)");
12230                            break;
12231                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12232                            pw.println("moderate)");
12233                            break;
12234                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12235                            pw.println("low)");
12236                            break;
12237                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12238                            pw.println("critical)");
12239                            break;
12240                        default:
12241                            pw.print(mLastMemoryLevel);
12242                            pw.println(")");
12243                            break;
12244                    }
12245                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12246                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12247                            pw.print(cachedPss); pw.print(" cached pss + ");
12248                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12249                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12250                } else {
12251                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12252                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12253                            + memInfo.getFreeSizeKb()); pw.print(",");
12254                    pw.println(totalPss - cachedPss);
12255                }
12256            }
12257            if (!isCompact) {
12258                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12259                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12260                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12261                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12262                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12263                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12264                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12265                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12266                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12267                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12268                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12269            }
12270            if (!brief) {
12271                if (memInfo.getZramTotalSizeKb() != 0) {
12272                    if (!isCompact) {
12273                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12274                                pw.print(" kB physical used for ");
12275                                pw.print(memInfo.getSwapTotalSizeKb()
12276                                        - memInfo.getSwapFreeSizeKb());
12277                                pw.print(" kB in swap (");
12278                                pw.print(memInfo.getSwapTotalSizeKb());
12279                                pw.println(" kB total swap)");
12280                    } else {
12281                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12282                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12283                                pw.println(memInfo.getSwapFreeSizeKb());
12284                    }
12285                }
12286                final int[] SINGLE_LONG_FORMAT = new int[] {
12287                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12288                };
12289                long[] longOut = new long[1];
12290                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12291                        SINGLE_LONG_FORMAT, null, longOut, null);
12292                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12293                longOut[0] = 0;
12294                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12295                        SINGLE_LONG_FORMAT, null, longOut, null);
12296                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12297                longOut[0] = 0;
12298                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12299                        SINGLE_LONG_FORMAT, null, longOut, null);
12300                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12301                longOut[0] = 0;
12302                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12303                        SINGLE_LONG_FORMAT, null, longOut, null);
12304                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12305                if (!isCompact) {
12306                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12307                        pw.print("      KSM: "); pw.print(sharing);
12308                                pw.print(" kB saved from shared ");
12309                                pw.print(shared); pw.println(" kB");
12310                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12311                                pw.print(voltile); pw.println(" kB volatile");
12312                    }
12313                    pw.print("   Tuning: ");
12314                    pw.print(ActivityManager.staticGetMemoryClass());
12315                    pw.print(" (large ");
12316                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12317                    pw.print("), oom ");
12318                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12319                    pw.print(" kB");
12320                    pw.print(", restore limit ");
12321                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12322                    pw.print(" kB");
12323                    if (ActivityManager.isLowRamDeviceStatic()) {
12324                        pw.print(" (low-ram)");
12325                    }
12326                    if (ActivityManager.isHighEndGfx()) {
12327                        pw.print(" (high-end-gfx)");
12328                    }
12329                    pw.println();
12330                } else {
12331                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12332                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12333                    pw.println(voltile);
12334                    pw.print("tuning,");
12335                    pw.print(ActivityManager.staticGetMemoryClass());
12336                    pw.print(',');
12337                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12338                    pw.print(',');
12339                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12340                    if (ActivityManager.isLowRamDeviceStatic()) {
12341                        pw.print(",low-ram");
12342                    }
12343                    if (ActivityManager.isHighEndGfx()) {
12344                        pw.print(",high-end-gfx");
12345                    }
12346                    pw.println();
12347                }
12348            }
12349        }
12350    }
12351
12352    /**
12353     * Searches array of arguments for the specified string
12354     * @param args array of argument strings
12355     * @param value value to search for
12356     * @return true if the value is contained in the array
12357     */
12358    private static boolean scanArgs(String[] args, String value) {
12359        if (args != null) {
12360            for (String arg : args) {
12361                if (value.equals(arg)) {
12362                    return true;
12363                }
12364            }
12365        }
12366        return false;
12367    }
12368
12369    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12370            ContentProviderRecord cpr, boolean always) {
12371        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12372
12373        if (!inLaunching || always) {
12374            synchronized (cpr) {
12375                cpr.launchingApp = null;
12376                cpr.notifyAll();
12377            }
12378            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12379            String names[] = cpr.info.authority.split(";");
12380            for (int j = 0; j < names.length; j++) {
12381                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12382            }
12383        }
12384
12385        for (int i=0; i<cpr.connections.size(); i++) {
12386            ContentProviderConnection conn = cpr.connections.get(i);
12387            if (conn.waiting) {
12388                // If this connection is waiting for the provider, then we don't
12389                // need to mess with its process unless we are always removing
12390                // or for some reason the provider is not currently launching.
12391                if (inLaunching && !always) {
12392                    continue;
12393                }
12394            }
12395            ProcessRecord capp = conn.client;
12396            conn.dead = true;
12397            if (conn.stableCount > 0) {
12398                if (!capp.persistent && capp.thread != null
12399                        && capp.pid != 0
12400                        && capp.pid != MY_PID) {
12401                    killUnneededProcessLocked(capp, "depends on provider "
12402                            + cpr.name.flattenToShortString()
12403                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12404                }
12405            } else if (capp.thread != null && conn.provider.provider != null) {
12406                try {
12407                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12408                } catch (RemoteException e) {
12409                }
12410                // In the protocol here, we don't expect the client to correctly
12411                // clean up this connection, we'll just remove it.
12412                cpr.connections.remove(i);
12413                conn.client.conProviders.remove(conn);
12414            }
12415        }
12416
12417        if (inLaunching && always) {
12418            mLaunchingProviders.remove(cpr);
12419        }
12420        return inLaunching;
12421    }
12422
12423    /**
12424     * Main code for cleaning up a process when it has gone away.  This is
12425     * called both as a result of the process dying, or directly when stopping
12426     * a process when running in single process mode.
12427     */
12428    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12429            boolean restarting, boolean allowRestart, int index) {
12430        if (index >= 0) {
12431            removeLruProcessLocked(app);
12432            ProcessList.remove(app.pid);
12433        }
12434
12435        mProcessesToGc.remove(app);
12436        mPendingPssProcesses.remove(app);
12437
12438        // Dismiss any open dialogs.
12439        if (app.crashDialog != null && !app.forceCrashReport) {
12440            app.crashDialog.dismiss();
12441            app.crashDialog = null;
12442        }
12443        if (app.anrDialog != null) {
12444            app.anrDialog.dismiss();
12445            app.anrDialog = null;
12446        }
12447        if (app.waitDialog != null) {
12448            app.waitDialog.dismiss();
12449            app.waitDialog = null;
12450        }
12451
12452        app.crashing = false;
12453        app.notResponding = false;
12454
12455        app.resetPackageList(mProcessStats);
12456        app.unlinkDeathRecipient();
12457        app.makeInactive(mProcessStats);
12458        app.forcingToForeground = null;
12459        updateProcessForegroundLocked(app, false, false);
12460        app.foregroundActivities = false;
12461        app.hasShownUi = false;
12462        app.hasAboveClient = false;
12463
12464        mServices.killServicesLocked(app, allowRestart);
12465
12466        boolean restart = false;
12467
12468        // Remove published content providers.
12469        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12470            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12471            final boolean always = app.bad || !allowRestart;
12472            if (removeDyingProviderLocked(app, cpr, always) || always) {
12473                // We left the provider in the launching list, need to
12474                // restart it.
12475                restart = true;
12476            }
12477
12478            cpr.provider = null;
12479            cpr.proc = null;
12480        }
12481        app.pubProviders.clear();
12482
12483        // Take care of any launching providers waiting for this process.
12484        if (checkAppInLaunchingProvidersLocked(app, false)) {
12485            restart = true;
12486        }
12487
12488        // Unregister from connected content providers.
12489        if (!app.conProviders.isEmpty()) {
12490            for (int i=0; i<app.conProviders.size(); i++) {
12491                ContentProviderConnection conn = app.conProviders.get(i);
12492                conn.provider.connections.remove(conn);
12493            }
12494            app.conProviders.clear();
12495        }
12496
12497        // At this point there may be remaining entries in mLaunchingProviders
12498        // where we were the only one waiting, so they are no longer of use.
12499        // Look for these and clean up if found.
12500        // XXX Commented out for now.  Trying to figure out a way to reproduce
12501        // the actual situation to identify what is actually going on.
12502        if (false) {
12503            for (int i=0; i<mLaunchingProviders.size(); i++) {
12504                ContentProviderRecord cpr = (ContentProviderRecord)
12505                        mLaunchingProviders.get(i);
12506                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12507                    synchronized (cpr) {
12508                        cpr.launchingApp = null;
12509                        cpr.notifyAll();
12510                    }
12511                }
12512            }
12513        }
12514
12515        skipCurrentReceiverLocked(app);
12516
12517        // Unregister any receivers.
12518        for (int i=app.receivers.size()-1; i>=0; i--) {
12519            removeReceiverLocked(app.receivers.valueAt(i));
12520        }
12521        app.receivers.clear();
12522
12523        // If the app is undergoing backup, tell the backup manager about it
12524        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12525            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12526                    + mBackupTarget.appInfo + " died during backup");
12527            try {
12528                IBackupManager bm = IBackupManager.Stub.asInterface(
12529                        ServiceManager.getService(Context.BACKUP_SERVICE));
12530                bm.agentDisconnected(app.info.packageName);
12531            } catch (RemoteException e) {
12532                // can't happen; backup manager is local
12533            }
12534        }
12535
12536        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12537            ProcessChangeItem item = mPendingProcessChanges.get(i);
12538            if (item.pid == app.pid) {
12539                mPendingProcessChanges.remove(i);
12540                mAvailProcessChanges.add(item);
12541            }
12542        }
12543        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12544
12545        // If the caller is restarting this app, then leave it in its
12546        // current lists and let the caller take care of it.
12547        if (restarting) {
12548            return;
12549        }
12550
12551        if (!app.persistent || app.isolated) {
12552            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12553                    "Removing non-persistent process during cleanup: " + app);
12554            mProcessNames.remove(app.processName, app.uid);
12555            mIsolatedProcesses.remove(app.uid);
12556            if (mHeavyWeightProcess == app) {
12557                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12558                        mHeavyWeightProcess.userId, 0));
12559                mHeavyWeightProcess = null;
12560            }
12561        } else if (!app.removed) {
12562            // This app is persistent, so we need to keep its record around.
12563            // If it is not already on the pending app list, add it there
12564            // and start a new process for it.
12565            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12566                mPersistentStartingProcesses.add(app);
12567                restart = true;
12568            }
12569        }
12570        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12571                "Clean-up removing on hold: " + app);
12572        mProcessesOnHold.remove(app);
12573
12574        if (app == mHomeProcess) {
12575            mHomeProcess = null;
12576        }
12577        if (app == mPreviousProcess) {
12578            mPreviousProcess = null;
12579        }
12580
12581        if (restart && !app.isolated) {
12582            // We have components that still need to be running in the
12583            // process, so re-launch it.
12584            mProcessNames.put(app.processName, app.uid, app);
12585            startProcessLocked(app, "restart", app.processName);
12586        } else if (app.pid > 0 && app.pid != MY_PID) {
12587            // Goodbye!
12588            boolean removed;
12589            synchronized (mPidsSelfLocked) {
12590                mPidsSelfLocked.remove(app.pid);
12591                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12592            }
12593            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12594                    app.processName, app.info.uid);
12595            if (app.isolated) {
12596                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12597            }
12598            app.setPid(0);
12599        }
12600    }
12601
12602    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12603        // Look through the content providers we are waiting to have launched,
12604        // and if any run in this process then either schedule a restart of
12605        // the process or kill the client waiting for it if this process has
12606        // gone bad.
12607        int NL = mLaunchingProviders.size();
12608        boolean restart = false;
12609        for (int i=0; i<NL; i++) {
12610            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12611            if (cpr.launchingApp == app) {
12612                if (!alwaysBad && !app.bad) {
12613                    restart = true;
12614                } else {
12615                    removeDyingProviderLocked(app, cpr, true);
12616                    // cpr should have been removed from mLaunchingProviders
12617                    NL = mLaunchingProviders.size();
12618                    i--;
12619                }
12620            }
12621        }
12622        return restart;
12623    }
12624
12625    // =========================================================
12626    // SERVICES
12627    // =========================================================
12628
12629    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12630            int flags) {
12631        enforceNotIsolatedCaller("getServices");
12632        synchronized (this) {
12633            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12634        }
12635    }
12636
12637    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12638        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12639        synchronized (this) {
12640            return mServices.getRunningServiceControlPanelLocked(name);
12641        }
12642    }
12643
12644    public ComponentName startService(IApplicationThread caller, Intent service,
12645            String resolvedType, int userId) {
12646        enforceNotIsolatedCaller("startService");
12647        // Refuse possible leaked file descriptors
12648        if (service != null && service.hasFileDescriptors() == true) {
12649            throw new IllegalArgumentException("File descriptors passed in Intent");
12650        }
12651
12652        if (DEBUG_SERVICE)
12653            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12654        synchronized(this) {
12655            final int callingPid = Binder.getCallingPid();
12656            final int callingUid = Binder.getCallingUid();
12657            final long origId = Binder.clearCallingIdentity();
12658            ComponentName res = mServices.startServiceLocked(caller, service,
12659                    resolvedType, callingPid, callingUid, userId);
12660            Binder.restoreCallingIdentity(origId);
12661            return res;
12662        }
12663    }
12664
12665    ComponentName startServiceInPackage(int uid,
12666            Intent service, String resolvedType, int userId) {
12667        synchronized(this) {
12668            if (DEBUG_SERVICE)
12669                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12670            final long origId = Binder.clearCallingIdentity();
12671            ComponentName res = mServices.startServiceLocked(null, service,
12672                    resolvedType, -1, uid, userId);
12673            Binder.restoreCallingIdentity(origId);
12674            return res;
12675        }
12676    }
12677
12678    public int stopService(IApplicationThread caller, Intent service,
12679            String resolvedType, int userId) {
12680        enforceNotIsolatedCaller("stopService");
12681        // Refuse possible leaked file descriptors
12682        if (service != null && service.hasFileDescriptors() == true) {
12683            throw new IllegalArgumentException("File descriptors passed in Intent");
12684        }
12685
12686        synchronized(this) {
12687            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12688        }
12689    }
12690
12691    public IBinder peekService(Intent service, String resolvedType) {
12692        enforceNotIsolatedCaller("peekService");
12693        // Refuse possible leaked file descriptors
12694        if (service != null && service.hasFileDescriptors() == true) {
12695            throw new IllegalArgumentException("File descriptors passed in Intent");
12696        }
12697        synchronized(this) {
12698            return mServices.peekServiceLocked(service, resolvedType);
12699        }
12700    }
12701
12702    public boolean stopServiceToken(ComponentName className, IBinder token,
12703            int startId) {
12704        synchronized(this) {
12705            return mServices.stopServiceTokenLocked(className, token, startId);
12706        }
12707    }
12708
12709    public void setServiceForeground(ComponentName className, IBinder token,
12710            int id, Notification notification, boolean removeNotification) {
12711        synchronized(this) {
12712            mServices.setServiceForegroundLocked(className, token, id, notification,
12713                    removeNotification);
12714        }
12715    }
12716
12717    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12718            boolean requireFull, String name, String callerPackage) {
12719        final int callingUserId = UserHandle.getUserId(callingUid);
12720        if (callingUserId != userId) {
12721            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12722                if ((requireFull || checkComponentPermission(
12723                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12724                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12725                        && checkComponentPermission(
12726                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12727                                callingPid, callingUid, -1, true)
12728                                != PackageManager.PERMISSION_GRANTED) {
12729                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12730                        // In this case, they would like to just execute as their
12731                        // owner user instead of failing.
12732                        userId = callingUserId;
12733                    } else {
12734                        StringBuilder builder = new StringBuilder(128);
12735                        builder.append("Permission Denial: ");
12736                        builder.append(name);
12737                        if (callerPackage != null) {
12738                            builder.append(" from ");
12739                            builder.append(callerPackage);
12740                        }
12741                        builder.append(" asks to run as user ");
12742                        builder.append(userId);
12743                        builder.append(" but is calling from user ");
12744                        builder.append(UserHandle.getUserId(callingUid));
12745                        builder.append("; this requires ");
12746                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12747                        if (!requireFull) {
12748                            builder.append(" or ");
12749                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12750                        }
12751                        String msg = builder.toString();
12752                        Slog.w(TAG, msg);
12753                        throw new SecurityException(msg);
12754                    }
12755                }
12756            }
12757            if (userId == UserHandle.USER_CURRENT
12758                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12759                // Note that we may be accessing this outside of a lock...
12760                // shouldn't be a big deal, if this is being called outside
12761                // of a locked context there is intrinsically a race with
12762                // the value the caller will receive and someone else changing it.
12763                userId = mCurrentUserId;
12764            }
12765            if (!allowAll && userId < 0) {
12766                throw new IllegalArgumentException(
12767                        "Call does not support special user #" + userId);
12768            }
12769        }
12770        return userId;
12771    }
12772
12773    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12774            String className, int flags) {
12775        boolean result = false;
12776        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12777            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12778                if (ActivityManager.checkUidPermission(
12779                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12780                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12781                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12782                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12783                            + " requests FLAG_SINGLE_USER, but app does not hold "
12784                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12785                    Slog.w(TAG, msg);
12786                    throw new SecurityException(msg);
12787                }
12788                result = true;
12789            }
12790        } else if (componentProcessName == aInfo.packageName) {
12791            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12792        } else if ("system".equals(componentProcessName)) {
12793            result = true;
12794        }
12795        if (DEBUG_MU) {
12796            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12797                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12798        }
12799        return result;
12800    }
12801
12802    public int bindService(IApplicationThread caller, IBinder token,
12803            Intent service, String resolvedType,
12804            IServiceConnection connection, int flags, int userId) {
12805        enforceNotIsolatedCaller("bindService");
12806        // Refuse possible leaked file descriptors
12807        if (service != null && service.hasFileDescriptors() == true) {
12808            throw new IllegalArgumentException("File descriptors passed in Intent");
12809        }
12810
12811        synchronized(this) {
12812            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12813                    connection, flags, userId);
12814        }
12815    }
12816
12817    public boolean unbindService(IServiceConnection connection) {
12818        synchronized (this) {
12819            return mServices.unbindServiceLocked(connection);
12820        }
12821    }
12822
12823    public void publishService(IBinder token, Intent intent, IBinder service) {
12824        // Refuse possible leaked file descriptors
12825        if (intent != null && intent.hasFileDescriptors() == true) {
12826            throw new IllegalArgumentException("File descriptors passed in Intent");
12827        }
12828
12829        synchronized(this) {
12830            if (!(token instanceof ServiceRecord)) {
12831                throw new IllegalArgumentException("Invalid service token");
12832            }
12833            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12834        }
12835    }
12836
12837    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12838        // Refuse possible leaked file descriptors
12839        if (intent != null && intent.hasFileDescriptors() == true) {
12840            throw new IllegalArgumentException("File descriptors passed in Intent");
12841        }
12842
12843        synchronized(this) {
12844            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12845        }
12846    }
12847
12848    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12849        synchronized(this) {
12850            if (!(token instanceof ServiceRecord)) {
12851                throw new IllegalArgumentException("Invalid service token");
12852            }
12853            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12854        }
12855    }
12856
12857    // =========================================================
12858    // BACKUP AND RESTORE
12859    // =========================================================
12860
12861    // Cause the target app to be launched if necessary and its backup agent
12862    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12863    // activity manager to announce its creation.
12864    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12865        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12866        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12867
12868        synchronized(this) {
12869            // !!! TODO: currently no check here that we're already bound
12870            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12871            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12872            synchronized (stats) {
12873                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12874            }
12875
12876            // Backup agent is now in use, its package can't be stopped.
12877            try {
12878                AppGlobals.getPackageManager().setPackageStoppedState(
12879                        app.packageName, false, UserHandle.getUserId(app.uid));
12880            } catch (RemoteException e) {
12881            } catch (IllegalArgumentException e) {
12882                Slog.w(TAG, "Failed trying to unstop package "
12883                        + app.packageName + ": " + e);
12884            }
12885
12886            BackupRecord r = new BackupRecord(ss, app, backupMode);
12887            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12888                    ? new ComponentName(app.packageName, app.backupAgentName)
12889                    : new ComponentName("android", "FullBackupAgent");
12890            // startProcessLocked() returns existing proc's record if it's already running
12891            ProcessRecord proc = startProcessLocked(app.processName, app,
12892                    false, 0, "backup", hostingName, false, false, false);
12893            if (proc == null) {
12894                Slog.e(TAG, "Unable to start backup agent process " + r);
12895                return false;
12896            }
12897
12898            r.app = proc;
12899            mBackupTarget = r;
12900            mBackupAppName = app.packageName;
12901
12902            // Try not to kill the process during backup
12903            updateOomAdjLocked(proc);
12904
12905            // If the process is already attached, schedule the creation of the backup agent now.
12906            // If it is not yet live, this will be done when it attaches to the framework.
12907            if (proc.thread != null) {
12908                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12909                try {
12910                    proc.thread.scheduleCreateBackupAgent(app,
12911                            compatibilityInfoForPackageLocked(app), backupMode);
12912                } catch (RemoteException e) {
12913                    // Will time out on the backup manager side
12914                }
12915            } else {
12916                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12917            }
12918            // Invariants: at this point, the target app process exists and the application
12919            // is either already running or in the process of coming up.  mBackupTarget and
12920            // mBackupAppName describe the app, so that when it binds back to the AM we
12921            // know that it's scheduled for a backup-agent operation.
12922        }
12923
12924        return true;
12925    }
12926
12927    @Override
12928    public void clearPendingBackup() {
12929        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12930        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12931
12932        synchronized (this) {
12933            mBackupTarget = null;
12934            mBackupAppName = null;
12935        }
12936    }
12937
12938    // A backup agent has just come up
12939    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12940        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12941                + " = " + agent);
12942
12943        synchronized(this) {
12944            if (!agentPackageName.equals(mBackupAppName)) {
12945                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12946                return;
12947            }
12948        }
12949
12950        long oldIdent = Binder.clearCallingIdentity();
12951        try {
12952            IBackupManager bm = IBackupManager.Stub.asInterface(
12953                    ServiceManager.getService(Context.BACKUP_SERVICE));
12954            bm.agentConnected(agentPackageName, agent);
12955        } catch (RemoteException e) {
12956            // can't happen; the backup manager service is local
12957        } catch (Exception e) {
12958            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12959            e.printStackTrace();
12960        } finally {
12961            Binder.restoreCallingIdentity(oldIdent);
12962        }
12963    }
12964
12965    // done with this agent
12966    public void unbindBackupAgent(ApplicationInfo appInfo) {
12967        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12968        if (appInfo == null) {
12969            Slog.w(TAG, "unbind backup agent for null app");
12970            return;
12971        }
12972
12973        synchronized(this) {
12974            try {
12975                if (mBackupAppName == null) {
12976                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12977                    return;
12978                }
12979
12980                if (!mBackupAppName.equals(appInfo.packageName)) {
12981                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12982                    return;
12983                }
12984
12985                // Not backing this app up any more; reset its OOM adjustment
12986                final ProcessRecord proc = mBackupTarget.app;
12987                updateOomAdjLocked(proc);
12988
12989                // If the app crashed during backup, 'thread' will be null here
12990                if (proc.thread != null) {
12991                    try {
12992                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12993                                compatibilityInfoForPackageLocked(appInfo));
12994                    } catch (Exception e) {
12995                        Slog.e(TAG, "Exception when unbinding backup agent:");
12996                        e.printStackTrace();
12997                    }
12998                }
12999            } finally {
13000                mBackupTarget = null;
13001                mBackupAppName = null;
13002            }
13003        }
13004    }
13005    // =========================================================
13006    // BROADCASTS
13007    // =========================================================
13008
13009    private final List getStickiesLocked(String action, IntentFilter filter,
13010            List cur, int userId) {
13011        final ContentResolver resolver = mContext.getContentResolver();
13012        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13013        if (stickies == null) {
13014            return cur;
13015        }
13016        final ArrayList<Intent> list = stickies.get(action);
13017        if (list == null) {
13018            return cur;
13019        }
13020        int N = list.size();
13021        for (int i=0; i<N; i++) {
13022            Intent intent = list.get(i);
13023            if (filter.match(resolver, intent, true, TAG) >= 0) {
13024                if (cur == null) {
13025                    cur = new ArrayList<Intent>();
13026                }
13027                cur.add(intent);
13028            }
13029        }
13030        return cur;
13031    }
13032
13033    boolean isPendingBroadcastProcessLocked(int pid) {
13034        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13035                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13036    }
13037
13038    void skipPendingBroadcastLocked(int pid) {
13039            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13040            for (BroadcastQueue queue : mBroadcastQueues) {
13041                queue.skipPendingBroadcastLocked(pid);
13042            }
13043    }
13044
13045    // The app just attached; send any pending broadcasts that it should receive
13046    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13047        boolean didSomething = false;
13048        for (BroadcastQueue queue : mBroadcastQueues) {
13049            didSomething |= queue.sendPendingBroadcastsLocked(app);
13050        }
13051        return didSomething;
13052    }
13053
13054    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13055            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13056        enforceNotIsolatedCaller("registerReceiver");
13057        int callingUid;
13058        int callingPid;
13059        synchronized(this) {
13060            ProcessRecord callerApp = null;
13061            if (caller != null) {
13062                callerApp = getRecordForAppLocked(caller);
13063                if (callerApp == null) {
13064                    throw new SecurityException(
13065                            "Unable to find app for caller " + caller
13066                            + " (pid=" + Binder.getCallingPid()
13067                            + ") when registering receiver " + receiver);
13068                }
13069                if (callerApp.info.uid != Process.SYSTEM_UID &&
13070                        !callerApp.pkgList.containsKey(callerPackage) &&
13071                        !"android".equals(callerPackage)) {
13072                    throw new SecurityException("Given caller package " + callerPackage
13073                            + " is not running in process " + callerApp);
13074                }
13075                callingUid = callerApp.info.uid;
13076                callingPid = callerApp.pid;
13077            } else {
13078                callerPackage = null;
13079                callingUid = Binder.getCallingUid();
13080                callingPid = Binder.getCallingPid();
13081            }
13082
13083            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13084                    true, true, "registerReceiver", callerPackage);
13085
13086            List allSticky = null;
13087
13088            // Look for any matching sticky broadcasts...
13089            Iterator actions = filter.actionsIterator();
13090            if (actions != null) {
13091                while (actions.hasNext()) {
13092                    String action = (String)actions.next();
13093                    allSticky = getStickiesLocked(action, filter, allSticky,
13094                            UserHandle.USER_ALL);
13095                    allSticky = getStickiesLocked(action, filter, allSticky,
13096                            UserHandle.getUserId(callingUid));
13097                }
13098            } else {
13099                allSticky = getStickiesLocked(null, filter, allSticky,
13100                        UserHandle.USER_ALL);
13101                allSticky = getStickiesLocked(null, filter, allSticky,
13102                        UserHandle.getUserId(callingUid));
13103            }
13104
13105            // The first sticky in the list is returned directly back to
13106            // the client.
13107            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13108
13109            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13110                    + ": " + sticky);
13111
13112            if (receiver == null) {
13113                return sticky;
13114            }
13115
13116            ReceiverList rl
13117                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13118            if (rl == null) {
13119                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13120                        userId, receiver);
13121                if (rl.app != null) {
13122                    rl.app.receivers.add(rl);
13123                } else {
13124                    try {
13125                        receiver.asBinder().linkToDeath(rl, 0);
13126                    } catch (RemoteException e) {
13127                        return sticky;
13128                    }
13129                    rl.linkedToDeath = true;
13130                }
13131                mRegisteredReceivers.put(receiver.asBinder(), rl);
13132            } else if (rl.uid != callingUid) {
13133                throw new IllegalArgumentException(
13134                        "Receiver requested to register for uid " + callingUid
13135                        + " was previously registered for uid " + rl.uid);
13136            } else if (rl.pid != callingPid) {
13137                throw new IllegalArgumentException(
13138                        "Receiver requested to register for pid " + callingPid
13139                        + " was previously registered for pid " + rl.pid);
13140            } else if (rl.userId != userId) {
13141                throw new IllegalArgumentException(
13142                        "Receiver requested to register for user " + userId
13143                        + " was previously registered for user " + rl.userId);
13144            }
13145            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13146                    permission, callingUid, userId);
13147            rl.add(bf);
13148            if (!bf.debugCheck()) {
13149                Slog.w(TAG, "==> For Dynamic broadast");
13150            }
13151            mReceiverResolver.addFilter(bf);
13152
13153            // Enqueue broadcasts for all existing stickies that match
13154            // this filter.
13155            if (allSticky != null) {
13156                ArrayList receivers = new ArrayList();
13157                receivers.add(bf);
13158
13159                int N = allSticky.size();
13160                for (int i=0; i<N; i++) {
13161                    Intent intent = (Intent)allSticky.get(i);
13162                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13163                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13164                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13165                            null, null, false, true, true, -1);
13166                    queue.enqueueParallelBroadcastLocked(r);
13167                    queue.scheduleBroadcastsLocked();
13168                }
13169            }
13170
13171            return sticky;
13172        }
13173    }
13174
13175    public void unregisterReceiver(IIntentReceiver receiver) {
13176        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13177
13178        final long origId = Binder.clearCallingIdentity();
13179        try {
13180            boolean doTrim = false;
13181
13182            synchronized(this) {
13183                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13184                if (rl != null) {
13185                    if (rl.curBroadcast != null) {
13186                        BroadcastRecord r = rl.curBroadcast;
13187                        final boolean doNext = finishReceiverLocked(
13188                                receiver.asBinder(), r.resultCode, r.resultData,
13189                                r.resultExtras, r.resultAbort);
13190                        if (doNext) {
13191                            doTrim = true;
13192                            r.queue.processNextBroadcast(false);
13193                        }
13194                    }
13195
13196                    if (rl.app != null) {
13197                        rl.app.receivers.remove(rl);
13198                    }
13199                    removeReceiverLocked(rl);
13200                    if (rl.linkedToDeath) {
13201                        rl.linkedToDeath = false;
13202                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13203                    }
13204                }
13205            }
13206
13207            // If we actually concluded any broadcasts, we might now be able
13208            // to trim the recipients' apps from our working set
13209            if (doTrim) {
13210                trimApplications();
13211                return;
13212            }
13213
13214        } finally {
13215            Binder.restoreCallingIdentity(origId);
13216        }
13217    }
13218
13219    void removeReceiverLocked(ReceiverList rl) {
13220        mRegisteredReceivers.remove(rl.receiver.asBinder());
13221        int N = rl.size();
13222        for (int i=0; i<N; i++) {
13223            mReceiverResolver.removeFilter(rl.get(i));
13224        }
13225    }
13226
13227    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13228        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13229            ProcessRecord r = mLruProcesses.get(i);
13230            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13231                try {
13232                    r.thread.dispatchPackageBroadcast(cmd, packages);
13233                } catch (RemoteException ex) {
13234                }
13235            }
13236        }
13237    }
13238
13239    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13240            int[] users) {
13241        List<ResolveInfo> receivers = null;
13242        try {
13243            HashSet<ComponentName> singleUserReceivers = null;
13244            boolean scannedFirstReceivers = false;
13245            for (int user : users) {
13246                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13247                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13248                if (user != 0 && newReceivers != null) {
13249                    // If this is not the primary user, we need to check for
13250                    // any receivers that should be filtered out.
13251                    for (int i=0; i<newReceivers.size(); i++) {
13252                        ResolveInfo ri = newReceivers.get(i);
13253                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13254                            newReceivers.remove(i);
13255                            i--;
13256                        }
13257                    }
13258                }
13259                if (newReceivers != null && newReceivers.size() == 0) {
13260                    newReceivers = null;
13261                }
13262                if (receivers == null) {
13263                    receivers = newReceivers;
13264                } else if (newReceivers != null) {
13265                    // We need to concatenate the additional receivers
13266                    // found with what we have do far.  This would be easy,
13267                    // but we also need to de-dup any receivers that are
13268                    // singleUser.
13269                    if (!scannedFirstReceivers) {
13270                        // Collect any single user receivers we had already retrieved.
13271                        scannedFirstReceivers = true;
13272                        for (int i=0; i<receivers.size(); i++) {
13273                            ResolveInfo ri = receivers.get(i);
13274                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13275                                ComponentName cn = new ComponentName(
13276                                        ri.activityInfo.packageName, ri.activityInfo.name);
13277                                if (singleUserReceivers == null) {
13278                                    singleUserReceivers = new HashSet<ComponentName>();
13279                                }
13280                                singleUserReceivers.add(cn);
13281                            }
13282                        }
13283                    }
13284                    // Add the new results to the existing results, tracking
13285                    // and de-dupping single user receivers.
13286                    for (int i=0; i<newReceivers.size(); i++) {
13287                        ResolveInfo ri = newReceivers.get(i);
13288                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13289                            ComponentName cn = new ComponentName(
13290                                    ri.activityInfo.packageName, ri.activityInfo.name);
13291                            if (singleUserReceivers == null) {
13292                                singleUserReceivers = new HashSet<ComponentName>();
13293                            }
13294                            if (!singleUserReceivers.contains(cn)) {
13295                                singleUserReceivers.add(cn);
13296                                receivers.add(ri);
13297                            }
13298                        } else {
13299                            receivers.add(ri);
13300                        }
13301                    }
13302                }
13303            }
13304        } catch (RemoteException ex) {
13305            // pm is in same process, this will never happen.
13306        }
13307        return receivers;
13308    }
13309
13310    private final int broadcastIntentLocked(ProcessRecord callerApp,
13311            String callerPackage, Intent intent, String resolvedType,
13312            IIntentReceiver resultTo, int resultCode, String resultData,
13313            Bundle map, String requiredPermission, int appOp,
13314            boolean ordered, boolean sticky, int callingPid, int callingUid,
13315            int userId) {
13316        intent = new Intent(intent);
13317
13318        // By default broadcasts do not go to stopped apps.
13319        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13320
13321        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13322            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13323            + " ordered=" + ordered + " userid=" + userId);
13324        if ((resultTo != null) && !ordered) {
13325            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13326        }
13327
13328        userId = handleIncomingUser(callingPid, callingUid, userId,
13329                true, false, "broadcast", callerPackage);
13330
13331        // Make sure that the user who is receiving this broadcast is started.
13332        // If not, we will just skip it.
13333        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13334            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13335                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13336                Slog.w(TAG, "Skipping broadcast of " + intent
13337                        + ": user " + userId + " is stopped");
13338                return ActivityManager.BROADCAST_SUCCESS;
13339            }
13340        }
13341
13342        /*
13343         * Prevent non-system code (defined here to be non-persistent
13344         * processes) from sending protected broadcasts.
13345         */
13346        int callingAppId = UserHandle.getAppId(callingUid);
13347        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13348            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13349            callingUid == 0) {
13350            // Always okay.
13351        } else if (callerApp == null || !callerApp.persistent) {
13352            try {
13353                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13354                        intent.getAction())) {
13355                    String msg = "Permission Denial: not allowed to send broadcast "
13356                            + intent.getAction() + " from pid="
13357                            + callingPid + ", uid=" + callingUid;
13358                    Slog.w(TAG, msg);
13359                    throw new SecurityException(msg);
13360                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13361                    // Special case for compatibility: we don't want apps to send this,
13362                    // but historically it has not been protected and apps may be using it
13363                    // to poke their own app widget.  So, instead of making it protected,
13364                    // just limit it to the caller.
13365                    if (callerApp == null) {
13366                        String msg = "Permission Denial: not allowed to send broadcast "
13367                                + intent.getAction() + " from unknown caller.";
13368                        Slog.w(TAG, msg);
13369                        throw new SecurityException(msg);
13370                    } else if (intent.getComponent() != null) {
13371                        // They are good enough to send to an explicit component...  verify
13372                        // it is being sent to the calling app.
13373                        if (!intent.getComponent().getPackageName().equals(
13374                                callerApp.info.packageName)) {
13375                            String msg = "Permission Denial: not allowed to send broadcast "
13376                                    + intent.getAction() + " to "
13377                                    + intent.getComponent().getPackageName() + " from "
13378                                    + callerApp.info.packageName;
13379                            Slog.w(TAG, msg);
13380                            throw new SecurityException(msg);
13381                        }
13382                    } else {
13383                        // Limit broadcast to their own package.
13384                        intent.setPackage(callerApp.info.packageName);
13385                    }
13386                }
13387            } catch (RemoteException e) {
13388                Slog.w(TAG, "Remote exception", e);
13389                return ActivityManager.BROADCAST_SUCCESS;
13390            }
13391        }
13392
13393        // Handle special intents: if this broadcast is from the package
13394        // manager about a package being removed, we need to remove all of
13395        // its activities from the history stack.
13396        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13397                intent.getAction());
13398        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13399                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13400                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13401                || uidRemoved) {
13402            if (checkComponentPermission(
13403                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13404                    callingPid, callingUid, -1, true)
13405                    == PackageManager.PERMISSION_GRANTED) {
13406                if (uidRemoved) {
13407                    final Bundle intentExtras = intent.getExtras();
13408                    final int uid = intentExtras != null
13409                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13410                    if (uid >= 0) {
13411                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13412                        synchronized (bs) {
13413                            bs.removeUidStatsLocked(uid);
13414                        }
13415                        mAppOpsService.uidRemoved(uid);
13416                    }
13417                } else {
13418                    // If resources are unavailable just force stop all
13419                    // those packages and flush the attribute cache as well.
13420                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13421                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13422                        if (list != null && (list.length > 0)) {
13423                            for (String pkg : list) {
13424                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13425                                        "storage unmount");
13426                            }
13427                            sendPackageBroadcastLocked(
13428                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13429                        }
13430                    } else {
13431                        Uri data = intent.getData();
13432                        String ssp;
13433                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13434                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13435                                    intent.getAction());
13436                            boolean fullUninstall = removed &&
13437                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13438                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13439                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13440                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13441                                        false, fullUninstall, userId,
13442                                        removed ? "pkg removed" : "pkg changed");
13443                            }
13444                            if (removed) {
13445                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13446                                        new String[] {ssp}, userId);
13447                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13448                                    mAppOpsService.packageRemoved(
13449                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13450
13451                                    // Remove all permissions granted from/to this package
13452                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13453                                }
13454                            }
13455                        }
13456                    }
13457                }
13458            } else {
13459                String msg = "Permission Denial: " + intent.getAction()
13460                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13461                        + ", uid=" + callingUid + ")"
13462                        + " requires "
13463                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13464                Slog.w(TAG, msg);
13465                throw new SecurityException(msg);
13466            }
13467
13468        // Special case for adding a package: by default turn on compatibility
13469        // mode.
13470        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13471            Uri data = intent.getData();
13472            String ssp;
13473            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13474                mCompatModePackages.handlePackageAddedLocked(ssp,
13475                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13476            }
13477        }
13478
13479        /*
13480         * If this is the time zone changed action, queue up a message that will reset the timezone
13481         * of all currently running processes. This message will get queued up before the broadcast
13482         * happens.
13483         */
13484        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13485            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13486        }
13487
13488        /*
13489         * If the user set the time, let all running processes know.
13490         */
13491        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13492            final int is24Hour = intent.getBooleanExtra(
13493                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13494            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13495        }
13496
13497        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13498            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13499        }
13500
13501        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13502            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13503            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13504        }
13505
13506        // Add to the sticky list if requested.
13507        if (sticky) {
13508            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13509                    callingPid, callingUid)
13510                    != PackageManager.PERMISSION_GRANTED) {
13511                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13512                        + callingPid + ", uid=" + callingUid
13513                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13514                Slog.w(TAG, msg);
13515                throw new SecurityException(msg);
13516            }
13517            if (requiredPermission != null) {
13518                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13519                        + " and enforce permission " + requiredPermission);
13520                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13521            }
13522            if (intent.getComponent() != null) {
13523                throw new SecurityException(
13524                        "Sticky broadcasts can't target a specific component");
13525            }
13526            // We use userId directly here, since the "all" target is maintained
13527            // as a separate set of sticky broadcasts.
13528            if (userId != UserHandle.USER_ALL) {
13529                // But first, if this is not a broadcast to all users, then
13530                // make sure it doesn't conflict with an existing broadcast to
13531                // all users.
13532                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13533                        UserHandle.USER_ALL);
13534                if (stickies != null) {
13535                    ArrayList<Intent> list = stickies.get(intent.getAction());
13536                    if (list != null) {
13537                        int N = list.size();
13538                        int i;
13539                        for (i=0; i<N; i++) {
13540                            if (intent.filterEquals(list.get(i))) {
13541                                throw new IllegalArgumentException(
13542                                        "Sticky broadcast " + intent + " for user "
13543                                        + userId + " conflicts with existing global broadcast");
13544                            }
13545                        }
13546                    }
13547                }
13548            }
13549            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13550            if (stickies == null) {
13551                stickies = new ArrayMap<String, ArrayList<Intent>>();
13552                mStickyBroadcasts.put(userId, stickies);
13553            }
13554            ArrayList<Intent> list = stickies.get(intent.getAction());
13555            if (list == null) {
13556                list = new ArrayList<Intent>();
13557                stickies.put(intent.getAction(), list);
13558            }
13559            int N = list.size();
13560            int i;
13561            for (i=0; i<N; i++) {
13562                if (intent.filterEquals(list.get(i))) {
13563                    // This sticky already exists, replace it.
13564                    list.set(i, new Intent(intent));
13565                    break;
13566                }
13567            }
13568            if (i >= N) {
13569                list.add(new Intent(intent));
13570            }
13571        }
13572
13573        int[] users;
13574        if (userId == UserHandle.USER_ALL) {
13575            // Caller wants broadcast to go to all started users.
13576            users = mStartedUserArray;
13577        } else {
13578            // Caller wants broadcast to go to one specific user.
13579            users = new int[] {userId};
13580        }
13581
13582        // Figure out who all will receive this broadcast.
13583        List receivers = null;
13584        List<BroadcastFilter> registeredReceivers = null;
13585        // Need to resolve the intent to interested receivers...
13586        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13587                 == 0) {
13588            receivers = collectReceiverComponents(intent, resolvedType, users);
13589        }
13590        if (intent.getComponent() == null) {
13591            registeredReceivers = mReceiverResolver.queryIntent(intent,
13592                    resolvedType, false, userId);
13593        }
13594
13595        final boolean replacePending =
13596                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13597
13598        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13599                + " replacePending=" + replacePending);
13600
13601        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13602        if (!ordered && NR > 0) {
13603            // If we are not serializing this broadcast, then send the
13604            // registered receivers separately so they don't wait for the
13605            // components to be launched.
13606            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13607            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13608                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13609                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13610                    ordered, sticky, false, userId);
13611            if (DEBUG_BROADCAST) Slog.v(
13612                    TAG, "Enqueueing parallel broadcast " + r);
13613            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13614            if (!replaced) {
13615                queue.enqueueParallelBroadcastLocked(r);
13616                queue.scheduleBroadcastsLocked();
13617            }
13618            registeredReceivers = null;
13619            NR = 0;
13620        }
13621
13622        // Merge into one list.
13623        int ir = 0;
13624        if (receivers != null) {
13625            // A special case for PACKAGE_ADDED: do not allow the package
13626            // being added to see this broadcast.  This prevents them from
13627            // using this as a back door to get run as soon as they are
13628            // installed.  Maybe in the future we want to have a special install
13629            // broadcast or such for apps, but we'd like to deliberately make
13630            // this decision.
13631            String skipPackages[] = null;
13632            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13633                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13634                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13635                Uri data = intent.getData();
13636                if (data != null) {
13637                    String pkgName = data.getSchemeSpecificPart();
13638                    if (pkgName != null) {
13639                        skipPackages = new String[] { pkgName };
13640                    }
13641                }
13642            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13643                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13644            }
13645            if (skipPackages != null && (skipPackages.length > 0)) {
13646                for (String skipPackage : skipPackages) {
13647                    if (skipPackage != null) {
13648                        int NT = receivers.size();
13649                        for (int it=0; it<NT; it++) {
13650                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13651                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13652                                receivers.remove(it);
13653                                it--;
13654                                NT--;
13655                            }
13656                        }
13657                    }
13658                }
13659            }
13660
13661            int NT = receivers != null ? receivers.size() : 0;
13662            int it = 0;
13663            ResolveInfo curt = null;
13664            BroadcastFilter curr = null;
13665            while (it < NT && ir < NR) {
13666                if (curt == null) {
13667                    curt = (ResolveInfo)receivers.get(it);
13668                }
13669                if (curr == null) {
13670                    curr = registeredReceivers.get(ir);
13671                }
13672                if (curr.getPriority() >= curt.priority) {
13673                    // Insert this broadcast record into the final list.
13674                    receivers.add(it, curr);
13675                    ir++;
13676                    curr = null;
13677                    it++;
13678                    NT++;
13679                } else {
13680                    // Skip to the next ResolveInfo in the final list.
13681                    it++;
13682                    curt = null;
13683                }
13684            }
13685        }
13686        while (ir < NR) {
13687            if (receivers == null) {
13688                receivers = new ArrayList();
13689            }
13690            receivers.add(registeredReceivers.get(ir));
13691            ir++;
13692        }
13693
13694        if ((receivers != null && receivers.size() > 0)
13695                || resultTo != null) {
13696            BroadcastQueue queue = broadcastQueueForIntent(intent);
13697            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13698                    callerPackage, callingPid, callingUid, resolvedType,
13699                    requiredPermission, appOp, receivers, resultTo, resultCode,
13700                    resultData, map, ordered, sticky, false, userId);
13701            if (DEBUG_BROADCAST) Slog.v(
13702                    TAG, "Enqueueing ordered broadcast " + r
13703                    + ": prev had " + queue.mOrderedBroadcasts.size());
13704            if (DEBUG_BROADCAST) {
13705                int seq = r.intent.getIntExtra("seq", -1);
13706                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13707            }
13708            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13709            if (!replaced) {
13710                queue.enqueueOrderedBroadcastLocked(r);
13711                queue.scheduleBroadcastsLocked();
13712            }
13713        }
13714
13715        return ActivityManager.BROADCAST_SUCCESS;
13716    }
13717
13718    final Intent verifyBroadcastLocked(Intent intent) {
13719        // Refuse possible leaked file descriptors
13720        if (intent != null && intent.hasFileDescriptors() == true) {
13721            throw new IllegalArgumentException("File descriptors passed in Intent");
13722        }
13723
13724        int flags = intent.getFlags();
13725
13726        if (!mProcessesReady) {
13727            // if the caller really truly claims to know what they're doing, go
13728            // ahead and allow the broadcast without launching any receivers
13729            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13730                intent = new Intent(intent);
13731                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13732            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13733                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13734                        + " before boot completion");
13735                throw new IllegalStateException("Cannot broadcast before boot completed");
13736            }
13737        }
13738
13739        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13740            throw new IllegalArgumentException(
13741                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13742        }
13743
13744        return intent;
13745    }
13746
13747    public final int broadcastIntent(IApplicationThread caller,
13748            Intent intent, String resolvedType, IIntentReceiver resultTo,
13749            int resultCode, String resultData, Bundle map,
13750            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13751        enforceNotIsolatedCaller("broadcastIntent");
13752        synchronized(this) {
13753            intent = verifyBroadcastLocked(intent);
13754
13755            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13756            final int callingPid = Binder.getCallingPid();
13757            final int callingUid = Binder.getCallingUid();
13758            final long origId = Binder.clearCallingIdentity();
13759            int res = broadcastIntentLocked(callerApp,
13760                    callerApp != null ? callerApp.info.packageName : null,
13761                    intent, resolvedType, resultTo,
13762                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13763                    callingPid, callingUid, userId);
13764            Binder.restoreCallingIdentity(origId);
13765            return res;
13766        }
13767    }
13768
13769    int broadcastIntentInPackage(String packageName, int uid,
13770            Intent intent, String resolvedType, IIntentReceiver resultTo,
13771            int resultCode, String resultData, Bundle map,
13772            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13773        synchronized(this) {
13774            intent = verifyBroadcastLocked(intent);
13775
13776            final long origId = Binder.clearCallingIdentity();
13777            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13778                    resultTo, resultCode, resultData, map, requiredPermission,
13779                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13780            Binder.restoreCallingIdentity(origId);
13781            return res;
13782        }
13783    }
13784
13785    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13786        // Refuse possible leaked file descriptors
13787        if (intent != null && intent.hasFileDescriptors() == true) {
13788            throw new IllegalArgumentException("File descriptors passed in Intent");
13789        }
13790
13791        userId = handleIncomingUser(Binder.getCallingPid(),
13792                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13793
13794        synchronized(this) {
13795            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13796                    != PackageManager.PERMISSION_GRANTED) {
13797                String msg = "Permission Denial: unbroadcastIntent() from pid="
13798                        + Binder.getCallingPid()
13799                        + ", uid=" + Binder.getCallingUid()
13800                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13801                Slog.w(TAG, msg);
13802                throw new SecurityException(msg);
13803            }
13804            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13805            if (stickies != null) {
13806                ArrayList<Intent> list = stickies.get(intent.getAction());
13807                if (list != null) {
13808                    int N = list.size();
13809                    int i;
13810                    for (i=0; i<N; i++) {
13811                        if (intent.filterEquals(list.get(i))) {
13812                            list.remove(i);
13813                            break;
13814                        }
13815                    }
13816                    if (list.size() <= 0) {
13817                        stickies.remove(intent.getAction());
13818                    }
13819                }
13820                if (stickies.size() <= 0) {
13821                    mStickyBroadcasts.remove(userId);
13822                }
13823            }
13824        }
13825    }
13826
13827    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13828            String resultData, Bundle resultExtras, boolean resultAbort) {
13829        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13830        if (r == null) {
13831            Slog.w(TAG, "finishReceiver called but not found on queue");
13832            return false;
13833        }
13834
13835        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13836    }
13837
13838    void backgroundServicesFinishedLocked(int userId) {
13839        for (BroadcastQueue queue : mBroadcastQueues) {
13840            queue.backgroundServicesFinishedLocked(userId);
13841        }
13842    }
13843
13844    public void finishReceiver(IBinder who, int resultCode, String resultData,
13845            Bundle resultExtras, boolean resultAbort) {
13846        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13847
13848        // Refuse possible leaked file descriptors
13849        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13850            throw new IllegalArgumentException("File descriptors passed in Bundle");
13851        }
13852
13853        final long origId = Binder.clearCallingIdentity();
13854        try {
13855            boolean doNext = false;
13856            BroadcastRecord r;
13857
13858            synchronized(this) {
13859                r = broadcastRecordForReceiverLocked(who);
13860                if (r != null) {
13861                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13862                        resultData, resultExtras, resultAbort, true);
13863                }
13864            }
13865
13866            if (doNext) {
13867                r.queue.processNextBroadcast(false);
13868            }
13869            trimApplications();
13870        } finally {
13871            Binder.restoreCallingIdentity(origId);
13872        }
13873    }
13874
13875    // =========================================================
13876    // INSTRUMENTATION
13877    // =========================================================
13878
13879    public boolean startInstrumentation(ComponentName className,
13880            String profileFile, int flags, Bundle arguments,
13881            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13882            int userId) {
13883        enforceNotIsolatedCaller("startInstrumentation");
13884        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13885                userId, false, true, "startInstrumentation", null);
13886        // Refuse possible leaked file descriptors
13887        if (arguments != null && arguments.hasFileDescriptors()) {
13888            throw new IllegalArgumentException("File descriptors passed in Bundle");
13889        }
13890
13891        synchronized(this) {
13892            InstrumentationInfo ii = null;
13893            ApplicationInfo ai = null;
13894            try {
13895                ii = mContext.getPackageManager().getInstrumentationInfo(
13896                    className, STOCK_PM_FLAGS);
13897                ai = AppGlobals.getPackageManager().getApplicationInfo(
13898                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13899            } catch (PackageManager.NameNotFoundException e) {
13900            } catch (RemoteException e) {
13901            }
13902            if (ii == null) {
13903                reportStartInstrumentationFailure(watcher, className,
13904                        "Unable to find instrumentation info for: " + className);
13905                return false;
13906            }
13907            if (ai == null) {
13908                reportStartInstrumentationFailure(watcher, className,
13909                        "Unable to find instrumentation target package: " + ii.targetPackage);
13910                return false;
13911            }
13912
13913            int match = mContext.getPackageManager().checkSignatures(
13914                    ii.targetPackage, ii.packageName);
13915            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13916                String msg = "Permission Denial: starting instrumentation "
13917                        + className + " from pid="
13918                        + Binder.getCallingPid()
13919                        + ", uid=" + Binder.getCallingPid()
13920                        + " not allowed because package " + ii.packageName
13921                        + " does not have a signature matching the target "
13922                        + ii.targetPackage;
13923                reportStartInstrumentationFailure(watcher, className, msg);
13924                throw new SecurityException(msg);
13925            }
13926
13927            final long origId = Binder.clearCallingIdentity();
13928            // Instrumentation can kill and relaunch even persistent processes
13929            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
13930                    "start instr");
13931            ProcessRecord app = addAppLocked(ai, false);
13932            app.instrumentationClass = className;
13933            app.instrumentationInfo = ai;
13934            app.instrumentationProfileFile = profileFile;
13935            app.instrumentationArguments = arguments;
13936            app.instrumentationWatcher = watcher;
13937            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13938            app.instrumentationResultClass = className;
13939            Binder.restoreCallingIdentity(origId);
13940        }
13941
13942        return true;
13943    }
13944
13945    /**
13946     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13947     * error to the logs, but if somebody is watching, send the report there too.  This enables
13948     * the "am" command to report errors with more information.
13949     *
13950     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13951     * @param cn The component name of the instrumentation.
13952     * @param report The error report.
13953     */
13954    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13955            ComponentName cn, String report) {
13956        Slog.w(TAG, report);
13957        try {
13958            if (watcher != null) {
13959                Bundle results = new Bundle();
13960                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13961                results.putString("Error", report);
13962                watcher.instrumentationStatus(cn, -1, results);
13963            }
13964        } catch (RemoteException e) {
13965            Slog.w(TAG, e);
13966        }
13967    }
13968
13969    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13970        if (app.instrumentationWatcher != null) {
13971            try {
13972                // NOTE:  IInstrumentationWatcher *must* be oneway here
13973                app.instrumentationWatcher.instrumentationFinished(
13974                    app.instrumentationClass,
13975                    resultCode,
13976                    results);
13977            } catch (RemoteException e) {
13978            }
13979        }
13980        if (app.instrumentationUiAutomationConnection != null) {
13981            try {
13982                app.instrumentationUiAutomationConnection.shutdown();
13983            } catch (RemoteException re) {
13984                /* ignore */
13985            }
13986            // Only a UiAutomation can set this flag and now that
13987            // it is finished we make sure it is reset to its default.
13988            mUserIsMonkey = false;
13989        }
13990        app.instrumentationWatcher = null;
13991        app.instrumentationUiAutomationConnection = null;
13992        app.instrumentationClass = null;
13993        app.instrumentationInfo = null;
13994        app.instrumentationProfileFile = null;
13995        app.instrumentationArguments = null;
13996
13997        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
13998                "finished inst");
13999    }
14000
14001    public void finishInstrumentation(IApplicationThread target,
14002            int resultCode, Bundle results) {
14003        int userId = UserHandle.getCallingUserId();
14004        // Refuse possible leaked file descriptors
14005        if (results != null && results.hasFileDescriptors()) {
14006            throw new IllegalArgumentException("File descriptors passed in Intent");
14007        }
14008
14009        synchronized(this) {
14010            ProcessRecord app = getRecordForAppLocked(target);
14011            if (app == null) {
14012                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14013                return;
14014            }
14015            final long origId = Binder.clearCallingIdentity();
14016            finishInstrumentationLocked(app, resultCode, results);
14017            Binder.restoreCallingIdentity(origId);
14018        }
14019    }
14020
14021    // =========================================================
14022    // CONFIGURATION
14023    // =========================================================
14024
14025    public ConfigurationInfo getDeviceConfigurationInfo() {
14026        ConfigurationInfo config = new ConfigurationInfo();
14027        synchronized (this) {
14028            config.reqTouchScreen = mConfiguration.touchscreen;
14029            config.reqKeyboardType = mConfiguration.keyboard;
14030            config.reqNavigation = mConfiguration.navigation;
14031            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14032                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14033                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14034            }
14035            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14036                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14037                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14038            }
14039            config.reqGlEsVersion = GL_ES_VERSION;
14040        }
14041        return config;
14042    }
14043
14044    ActivityStack getFocusedStack() {
14045        return mStackSupervisor.getFocusedStack();
14046    }
14047
14048    public Configuration getConfiguration() {
14049        Configuration ci;
14050        synchronized(this) {
14051            ci = new Configuration(mConfiguration);
14052        }
14053        return ci;
14054    }
14055
14056    public void updatePersistentConfiguration(Configuration values) {
14057        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14058                "updateConfiguration()");
14059        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14060                "updateConfiguration()");
14061        if (values == null) {
14062            throw new NullPointerException("Configuration must not be null");
14063        }
14064
14065        synchronized(this) {
14066            final long origId = Binder.clearCallingIdentity();
14067            updateConfigurationLocked(values, null, true, false);
14068            Binder.restoreCallingIdentity(origId);
14069        }
14070    }
14071
14072    public void updateConfiguration(Configuration values) {
14073        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14074                "updateConfiguration()");
14075
14076        synchronized(this) {
14077            if (values == null && mWindowManager != null) {
14078                // sentinel: fetch the current configuration from the window manager
14079                values = mWindowManager.computeNewConfiguration();
14080            }
14081
14082            if (mWindowManager != null) {
14083                mProcessList.applyDisplaySize(mWindowManager);
14084            }
14085
14086            final long origId = Binder.clearCallingIdentity();
14087            if (values != null) {
14088                Settings.System.clearConfiguration(values);
14089            }
14090            updateConfigurationLocked(values, null, false, false);
14091            Binder.restoreCallingIdentity(origId);
14092        }
14093    }
14094
14095    /**
14096     * Do either or both things: (1) change the current configuration, and (2)
14097     * make sure the given activity is running with the (now) current
14098     * configuration.  Returns true if the activity has been left running, or
14099     * false if <var>starting</var> is being destroyed to match the new
14100     * configuration.
14101     * @param persistent TODO
14102     */
14103    boolean updateConfigurationLocked(Configuration values,
14104            ActivityRecord starting, boolean persistent, boolean initLocale) {
14105        int changes = 0;
14106
14107        if (values != null) {
14108            Configuration newConfig = new Configuration(mConfiguration);
14109            changes = newConfig.updateFrom(values);
14110            if (changes != 0) {
14111                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14112                    Slog.i(TAG, "Updating configuration to: " + values);
14113                }
14114
14115                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14116
14117                if (values.locale != null && !initLocale) {
14118                    saveLocaleLocked(values.locale,
14119                                     !values.locale.equals(mConfiguration.locale),
14120                                     values.userSetLocale);
14121                }
14122
14123                mConfigurationSeq++;
14124                if (mConfigurationSeq <= 0) {
14125                    mConfigurationSeq = 1;
14126                }
14127                newConfig.seq = mConfigurationSeq;
14128                mConfiguration = newConfig;
14129                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14130
14131                final Configuration configCopy = new Configuration(mConfiguration);
14132
14133                // TODO: If our config changes, should we auto dismiss any currently
14134                // showing dialogs?
14135                mShowDialogs = shouldShowDialogs(newConfig);
14136
14137                AttributeCache ac = AttributeCache.instance();
14138                if (ac != null) {
14139                    ac.updateConfiguration(configCopy);
14140                }
14141
14142                // Make sure all resources in our process are updated
14143                // right now, so that anyone who is going to retrieve
14144                // resource values after we return will be sure to get
14145                // the new ones.  This is especially important during
14146                // boot, where the first config change needs to guarantee
14147                // all resources have that config before following boot
14148                // code is executed.
14149                mSystemThread.applyConfigurationToResources(configCopy);
14150
14151                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14152                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14153                    msg.obj = new Configuration(configCopy);
14154                    mHandler.sendMessage(msg);
14155                }
14156
14157                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14158                    ProcessRecord app = mLruProcesses.get(i);
14159                    try {
14160                        if (app.thread != null) {
14161                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14162                                    + app.processName + " new config " + mConfiguration);
14163                            app.thread.scheduleConfigurationChanged(configCopy);
14164                        }
14165                    } catch (Exception e) {
14166                    }
14167                }
14168                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14169                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14170                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14171                        | Intent.FLAG_RECEIVER_FOREGROUND);
14172                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14173                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14174                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14175                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14176                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14177                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14178                    broadcastIntentLocked(null, null, intent,
14179                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14180                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14181                }
14182            }
14183        }
14184
14185        boolean kept = true;
14186        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14187        // mainStack is null during startup.
14188        if (mainStack != null) {
14189            if (changes != 0 && starting == null) {
14190                // If the configuration changed, and the caller is not already
14191                // in the process of starting an activity, then find the top
14192                // activity to check if its configuration needs to change.
14193                starting = mainStack.topRunningActivityLocked(null);
14194            }
14195
14196            if (starting != null) {
14197                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14198                // And we need to make sure at this point that all other activities
14199                // are made visible with the correct configuration.
14200                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14201            }
14202        }
14203
14204        if (values != null && mWindowManager != null) {
14205            mWindowManager.setNewConfiguration(mConfiguration);
14206        }
14207
14208        return kept;
14209    }
14210
14211    /**
14212     * Decide based on the configuration whether we should shouw the ANR,
14213     * crash, etc dialogs.  The idea is that if there is no affordnace to
14214     * press the on-screen buttons, we shouldn't show the dialog.
14215     *
14216     * A thought: SystemUI might also want to get told about this, the Power
14217     * dialog / global actions also might want different behaviors.
14218     */
14219    private static final boolean shouldShowDialogs(Configuration config) {
14220        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14221                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14222    }
14223
14224    /**
14225     * Save the locale.  You must be inside a synchronized (this) block.
14226     */
14227    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14228        if(isDiff) {
14229            SystemProperties.set("user.language", l.getLanguage());
14230            SystemProperties.set("user.region", l.getCountry());
14231        }
14232
14233        if(isPersist) {
14234            SystemProperties.set("persist.sys.language", l.getLanguage());
14235            SystemProperties.set("persist.sys.country", l.getCountry());
14236            SystemProperties.set("persist.sys.localevar", l.getVariant());
14237        }
14238    }
14239
14240    @Override
14241    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14242        ActivityRecord srec = ActivityRecord.forToken(token);
14243        return srec != null && srec.task.affinity != null &&
14244                srec.task.affinity.equals(destAffinity);
14245    }
14246
14247    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14248            Intent resultData) {
14249
14250        synchronized (this) {
14251            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14252            if (stack != null) {
14253                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14254            }
14255            return false;
14256        }
14257    }
14258
14259    public int getLaunchedFromUid(IBinder activityToken) {
14260        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14261        if (srec == null) {
14262            return -1;
14263        }
14264        return srec.launchedFromUid;
14265    }
14266
14267    public String getLaunchedFromPackage(IBinder activityToken) {
14268        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14269        if (srec == null) {
14270            return null;
14271        }
14272        return srec.launchedFromPackage;
14273    }
14274
14275    // =========================================================
14276    // LIFETIME MANAGEMENT
14277    // =========================================================
14278
14279    // Returns which broadcast queue the app is the current [or imminent] receiver
14280    // on, or 'null' if the app is not an active broadcast recipient.
14281    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14282        BroadcastRecord r = app.curReceiver;
14283        if (r != null) {
14284            return r.queue;
14285        }
14286
14287        // It's not the current receiver, but it might be starting up to become one
14288        synchronized (this) {
14289            for (BroadcastQueue queue : mBroadcastQueues) {
14290                r = queue.mPendingBroadcast;
14291                if (r != null && r.curApp == app) {
14292                    // found it; report which queue it's in
14293                    return queue;
14294                }
14295            }
14296        }
14297
14298        return null;
14299    }
14300
14301    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14302            boolean doingAll, long now) {
14303        if (mAdjSeq == app.adjSeq) {
14304            // This adjustment has already been computed.
14305            return app.curRawAdj;
14306        }
14307
14308        if (app.thread == null) {
14309            app.adjSeq = mAdjSeq;
14310            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14311            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14312            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14313        }
14314
14315        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14316        app.adjSource = null;
14317        app.adjTarget = null;
14318        app.empty = false;
14319        app.cached = false;
14320
14321        final int activitiesSize = app.activities.size();
14322
14323        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14324            // The max adjustment doesn't allow this app to be anything
14325            // below foreground, so it is not worth doing work for it.
14326            app.adjType = "fixed";
14327            app.adjSeq = mAdjSeq;
14328            app.curRawAdj = app.maxAdj;
14329            app.foregroundActivities = false;
14330            app.keeping = true;
14331            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14332            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14333            // System process can do UI, and when they do we want to have
14334            // them trim their memory after the user leaves the UI.  To
14335            // facilitate this, here we need to determine whether or not it
14336            // is currently showing UI.
14337            app.systemNoUi = true;
14338            if (app == TOP_APP) {
14339                app.systemNoUi = false;
14340            } else if (activitiesSize > 0) {
14341                for (int j = 0; j < activitiesSize; j++) {
14342                    final ActivityRecord r = app.activities.get(j);
14343                    if (r.visible) {
14344                        app.systemNoUi = false;
14345                    }
14346                }
14347            }
14348            if (!app.systemNoUi) {
14349                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14350            }
14351            return (app.curAdj=app.maxAdj);
14352        }
14353
14354        app.keeping = false;
14355        app.systemNoUi = false;
14356
14357        // Determine the importance of the process, starting with most
14358        // important to least, and assign an appropriate OOM adjustment.
14359        int adj;
14360        int schedGroup;
14361        int procState;
14362        boolean foregroundActivities = false;
14363        boolean interesting = false;
14364        BroadcastQueue queue;
14365        if (app == TOP_APP) {
14366            // The last app on the list is the foreground app.
14367            adj = ProcessList.FOREGROUND_APP_ADJ;
14368            schedGroup = Process.THREAD_GROUP_DEFAULT;
14369            app.adjType = "top-activity";
14370            foregroundActivities = true;
14371            interesting = true;
14372            procState = ActivityManager.PROCESS_STATE_TOP;
14373        } else if (app.instrumentationClass != null) {
14374            // Don't want to kill running instrumentation.
14375            adj = ProcessList.FOREGROUND_APP_ADJ;
14376            schedGroup = Process.THREAD_GROUP_DEFAULT;
14377            app.adjType = "instrumentation";
14378            interesting = true;
14379            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14380        } else if ((queue = isReceivingBroadcast(app)) != null) {
14381            // An app that is currently receiving a broadcast also
14382            // counts as being in the foreground for OOM killer purposes.
14383            // It's placed in a sched group based on the nature of the
14384            // broadcast as reflected by which queue it's active in.
14385            adj = ProcessList.FOREGROUND_APP_ADJ;
14386            schedGroup = (queue == mFgBroadcastQueue)
14387                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14388            app.adjType = "broadcast";
14389            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14390        } else if (app.executingServices.size() > 0) {
14391            // An app that is currently executing a service callback also
14392            // counts as being in the foreground.
14393            adj = ProcessList.FOREGROUND_APP_ADJ;
14394            schedGroup = app.execServicesFg ?
14395                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14396            app.adjType = "exec-service";
14397            procState = ActivityManager.PROCESS_STATE_SERVICE;
14398            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14399        } else {
14400            // As far as we know the process is empty.  We may change our mind later.
14401            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14402            // At this point we don't actually know the adjustment.  Use the cached adj
14403            // value that the caller wants us to.
14404            adj = cachedAdj;
14405            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14406            app.cached = true;
14407            app.empty = true;
14408            app.adjType = "cch-empty";
14409        }
14410
14411        // Examine all activities if not already foreground.
14412        if (!foregroundActivities && activitiesSize > 0) {
14413            for (int j = 0; j < activitiesSize; j++) {
14414                final ActivityRecord r = app.activities.get(j);
14415                if (r.app != app) {
14416                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14417                            + app + "?!?");
14418                    continue;
14419                }
14420                if (r.visible) {
14421                    // App has a visible activity; only upgrade adjustment.
14422                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14423                        adj = ProcessList.VISIBLE_APP_ADJ;
14424                        app.adjType = "visible";
14425                    }
14426                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14427                        procState = ActivityManager.PROCESS_STATE_TOP;
14428                    }
14429                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14430                    app.cached = false;
14431                    app.empty = false;
14432                    foregroundActivities = true;
14433                    break;
14434                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14435                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14436                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14437                        app.adjType = "pausing";
14438                    }
14439                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14440                        procState = ActivityManager.PROCESS_STATE_TOP;
14441                    }
14442                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14443                    app.cached = false;
14444                    app.empty = false;
14445                    foregroundActivities = true;
14446                } else if (r.state == ActivityState.STOPPING) {
14447                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14448                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14449                        app.adjType = "stopping";
14450                    }
14451                    // For the process state, we will at this point consider the
14452                    // process to be cached.  It will be cached either as an activity
14453                    // or empty depending on whether the activity is finishing.  We do
14454                    // this so that we can treat the process as cached for purposes of
14455                    // memory trimming (determing current memory level, trim command to
14456                    // send to process) since there can be an arbitrary number of stopping
14457                    // processes and they should soon all go into the cached state.
14458                    if (!r.finishing) {
14459                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14460                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14461                        }
14462                    }
14463                    app.cached = false;
14464                    app.empty = false;
14465                    foregroundActivities = true;
14466                } else {
14467                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14468                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14469                        app.adjType = "cch-act";
14470                    }
14471                }
14472            }
14473        }
14474
14475        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14476            if (app.foregroundServices) {
14477                // The user is aware of this app, so make it visible.
14478                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14479                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14480                app.cached = false;
14481                app.adjType = "fg-service";
14482                schedGroup = Process.THREAD_GROUP_DEFAULT;
14483            } else if (app.forcingToForeground != null) {
14484                // The user is aware of this app, so make it visible.
14485                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14486                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14487                app.cached = false;
14488                app.adjType = "force-fg";
14489                app.adjSource = app.forcingToForeground;
14490                schedGroup = Process.THREAD_GROUP_DEFAULT;
14491            }
14492        }
14493
14494        if (app.foregroundServices) {
14495            interesting = true;
14496        }
14497
14498        if (app == mHeavyWeightProcess) {
14499            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14500                // We don't want to kill the current heavy-weight process.
14501                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14502                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14503                app.cached = false;
14504                app.adjType = "heavy";
14505            }
14506            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14507                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14508            }
14509        }
14510
14511        if (app == mHomeProcess) {
14512            if (adj > ProcessList.HOME_APP_ADJ) {
14513                // This process is hosting what we currently consider to be the
14514                // home app, so we don't want to let it go into the background.
14515                adj = ProcessList.HOME_APP_ADJ;
14516                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14517                app.cached = false;
14518                app.adjType = "home";
14519            }
14520            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14521                procState = ActivityManager.PROCESS_STATE_HOME;
14522            }
14523        }
14524
14525        if (app == mPreviousProcess && app.activities.size() > 0) {
14526            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14527                // This was the previous process that showed UI to the user.
14528                // We want to try to keep it around more aggressively, to give
14529                // a good experience around switching between two apps.
14530                adj = ProcessList.PREVIOUS_APP_ADJ;
14531                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14532                app.cached = false;
14533                app.adjType = "previous";
14534            }
14535            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14536                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14537            }
14538        }
14539
14540        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14541                + " reason=" + app.adjType);
14542
14543        // By default, we use the computed adjustment.  It may be changed if
14544        // there are applications dependent on our services or providers, but
14545        // this gives us a baseline and makes sure we don't get into an
14546        // infinite recursion.
14547        app.adjSeq = mAdjSeq;
14548        app.curRawAdj = adj;
14549        app.hasStartedServices = false;
14550
14551        if (mBackupTarget != null && app == mBackupTarget.app) {
14552            // If possible we want to avoid killing apps while they're being backed up
14553            if (adj > ProcessList.BACKUP_APP_ADJ) {
14554                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14555                adj = ProcessList.BACKUP_APP_ADJ;
14556                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14557                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14558                }
14559                app.adjType = "backup";
14560                app.cached = false;
14561            }
14562            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14563                procState = ActivityManager.PROCESS_STATE_BACKUP;
14564            }
14565        }
14566
14567        boolean mayBeTop = false;
14568
14569        for (int is = app.services.size()-1;
14570                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14571                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14572                        || procState > ActivityManager.PROCESS_STATE_TOP);
14573                is--) {
14574            ServiceRecord s = app.services.valueAt(is);
14575            if (s.startRequested) {
14576                app.hasStartedServices = true;
14577                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14578                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14579                }
14580                if (app.hasShownUi && app != mHomeProcess) {
14581                    // If this process has shown some UI, let it immediately
14582                    // go to the LRU list because it may be pretty heavy with
14583                    // UI stuff.  We'll tag it with a label just to help
14584                    // debug and understand what is going on.
14585                    if (adj > ProcessList.SERVICE_ADJ) {
14586                        app.adjType = "cch-started-ui-services";
14587                    }
14588                } else {
14589                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14590                        // This service has seen some activity within
14591                        // recent memory, so we will keep its process ahead
14592                        // of the background processes.
14593                        if (adj > ProcessList.SERVICE_ADJ) {
14594                            adj = ProcessList.SERVICE_ADJ;
14595                            app.adjType = "started-services";
14596                            app.cached = false;
14597                        }
14598                    }
14599                    // If we have let the service slide into the background
14600                    // state, still have some text describing what it is doing
14601                    // even though the service no longer has an impact.
14602                    if (adj > ProcessList.SERVICE_ADJ) {
14603                        app.adjType = "cch-started-services";
14604                    }
14605                }
14606                // Don't kill this process because it is doing work; it
14607                // has said it is doing work.
14608                app.keeping = true;
14609            }
14610            for (int conni = s.connections.size()-1;
14611                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14612                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14613                            || procState > ActivityManager.PROCESS_STATE_TOP);
14614                    conni--) {
14615                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14616                for (int i = 0;
14617                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14618                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14619                                || procState > ActivityManager.PROCESS_STATE_TOP);
14620                        i++) {
14621                    // XXX should compute this based on the max of
14622                    // all connected clients.
14623                    ConnectionRecord cr = clist.get(i);
14624                    if (cr.binding.client == app) {
14625                        // Binding to ourself is not interesting.
14626                        continue;
14627                    }
14628                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14629                        ProcessRecord client = cr.binding.client;
14630                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14631                                TOP_APP, doingAll, now);
14632                        int clientProcState = client.curProcState;
14633                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14634                            // If the other app is cached for any reason, for purposes here
14635                            // we are going to consider it empty.  The specific cached state
14636                            // doesn't propagate except under certain conditions.
14637                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14638                        }
14639                        String adjType = null;
14640                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14641                            // Not doing bind OOM management, so treat
14642                            // this guy more like a started service.
14643                            if (app.hasShownUi && app != mHomeProcess) {
14644                                // If this process has shown some UI, let it immediately
14645                                // go to the LRU list because it may be pretty heavy with
14646                                // UI stuff.  We'll tag it with a label just to help
14647                                // debug and understand what is going on.
14648                                if (adj > clientAdj) {
14649                                    adjType = "cch-bound-ui-services";
14650                                }
14651                                app.cached = false;
14652                                clientAdj = adj;
14653                                clientProcState = procState;
14654                            } else {
14655                                if (now >= (s.lastActivity
14656                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14657                                    // This service has not seen activity within
14658                                    // recent memory, so allow it to drop to the
14659                                    // LRU list if there is no other reason to keep
14660                                    // it around.  We'll also tag it with a label just
14661                                    // to help debug and undertand what is going on.
14662                                    if (adj > clientAdj) {
14663                                        adjType = "cch-bound-services";
14664                                    }
14665                                    clientAdj = adj;
14666                                }
14667                            }
14668                        }
14669                        if (adj > clientAdj) {
14670                            // If this process has recently shown UI, and
14671                            // the process that is binding to it is less
14672                            // important than being visible, then we don't
14673                            // care about the binding as much as we care
14674                            // about letting this process get into the LRU
14675                            // list to be killed and restarted if needed for
14676                            // memory.
14677                            if (app.hasShownUi && app != mHomeProcess
14678                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14679                                adjType = "cch-bound-ui-services";
14680                            } else {
14681                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14682                                        |Context.BIND_IMPORTANT)) != 0) {
14683                                    adj = clientAdj;
14684                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14685                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14686                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14687                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14688                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14689                                    adj = clientAdj;
14690                                } else {
14691                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14692                                        adj = ProcessList.VISIBLE_APP_ADJ;
14693                                    }
14694                                }
14695                                if (!client.cached) {
14696                                    app.cached = false;
14697                                }
14698                                if (client.keeping) {
14699                                    app.keeping = true;
14700                                }
14701                                adjType = "service";
14702                            }
14703                        }
14704                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14705                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14706                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14707                            }
14708                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14709                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14710                                    // Special handling of clients who are in the top state.
14711                                    // We *may* want to consider this process to be in the
14712                                    // top state as well, but only if there is not another
14713                                    // reason for it to be running.  Being on the top is a
14714                                    // special state, meaning you are specifically running
14715                                    // for the current top app.  If the process is already
14716                                    // running in the background for some other reason, it
14717                                    // is more important to continue considering it to be
14718                                    // in the background state.
14719                                    mayBeTop = true;
14720                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14721                                } else {
14722                                    // Special handling for above-top states (persistent
14723                                    // processes).  These should not bring the current process
14724                                    // into the top state, since they are not on top.  Instead
14725                                    // give them the best state after that.
14726                                    clientProcState =
14727                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14728                                }
14729                            }
14730                        } else {
14731                            if (clientProcState <
14732                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14733                                clientProcState =
14734                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14735                            }
14736                        }
14737                        if (procState > clientProcState) {
14738                            procState = clientProcState;
14739                        }
14740                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14741                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14742                            app.pendingUiClean = true;
14743                        }
14744                        if (adjType != null) {
14745                            app.adjType = adjType;
14746                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14747                                    .REASON_SERVICE_IN_USE;
14748                            app.adjSource = cr.binding.client;
14749                            app.adjSourceOom = clientAdj;
14750                            app.adjTarget = s.name;
14751                        }
14752                    }
14753                    final ActivityRecord a = cr.activity;
14754                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14755                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14756                                (a.visible || a.state == ActivityState.RESUMED
14757                                 || a.state == ActivityState.PAUSING)) {
14758                            adj = ProcessList.FOREGROUND_APP_ADJ;
14759                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14760                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14761                            }
14762                            app.cached = false;
14763                            app.adjType = "service";
14764                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14765                                    .REASON_SERVICE_IN_USE;
14766                            app.adjSource = a;
14767                            app.adjSourceOom = adj;
14768                            app.adjTarget = s.name;
14769                        }
14770                    }
14771                }
14772            }
14773        }
14774
14775        for (int provi = app.pubProviders.size()-1;
14776                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14777                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14778                        || procState > ActivityManager.PROCESS_STATE_TOP);
14779                provi--) {
14780            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14781            for (int i = cpr.connections.size()-1;
14782                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14783                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14784                            || procState > ActivityManager.PROCESS_STATE_TOP);
14785                    i--) {
14786                ContentProviderConnection conn = cpr.connections.get(i);
14787                ProcessRecord client = conn.client;
14788                if (client == app) {
14789                    // Being our own client is not interesting.
14790                    continue;
14791                }
14792                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14793                int clientProcState = client.curProcState;
14794                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14795                    // If the other app is cached for any reason, for purposes here
14796                    // we are going to consider it empty.
14797                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14798                }
14799                if (adj > clientAdj) {
14800                    if (app.hasShownUi && app != mHomeProcess
14801                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14802                        app.adjType = "cch-ui-provider";
14803                    } else {
14804                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14805                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14806                        app.adjType = "provider";
14807                    }
14808                    app.cached &= client.cached;
14809                    app.keeping |= client.keeping;
14810                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14811                            .REASON_PROVIDER_IN_USE;
14812                    app.adjSource = client;
14813                    app.adjSourceOom = clientAdj;
14814                    app.adjTarget = cpr.name;
14815                }
14816                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14817                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14818                        // Special handling of clients who are in the top state.
14819                        // We *may* want to consider this process to be in the
14820                        // top state as well, but only if there is not another
14821                        // reason for it to be running.  Being on the top is a
14822                        // special state, meaning you are specifically running
14823                        // for the current top app.  If the process is already
14824                        // running in the background for some other reason, it
14825                        // is more important to continue considering it to be
14826                        // in the background state.
14827                        mayBeTop = true;
14828                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14829                    } else {
14830                        // Special handling for above-top states (persistent
14831                        // processes).  These should not bring the current process
14832                        // into the top state, since they are not on top.  Instead
14833                        // give them the best state after that.
14834                        clientProcState =
14835                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14836                    }
14837                }
14838                if (procState > clientProcState) {
14839                    procState = clientProcState;
14840                }
14841                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14842                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14843                }
14844            }
14845            // If the provider has external (non-framework) process
14846            // dependencies, ensure that its adjustment is at least
14847            // FOREGROUND_APP_ADJ.
14848            if (cpr.hasExternalProcessHandles()) {
14849                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14850                    adj = ProcessList.FOREGROUND_APP_ADJ;
14851                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14852                    app.cached = false;
14853                    app.keeping = true;
14854                    app.adjType = "provider";
14855                    app.adjTarget = cpr.name;
14856                }
14857                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14858                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14859                }
14860            }
14861        }
14862
14863        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14864            // A client of one of our services or providers is in the top state.  We
14865            // *may* want to be in the top state, but not if we are already running in
14866            // the background for some other reason.  For the decision here, we are going
14867            // to pick out a few specific states that we want to remain in when a client
14868            // is top (states that tend to be longer-term) and otherwise allow it to go
14869            // to the top state.
14870            switch (procState) {
14871                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14872                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14873                case ActivityManager.PROCESS_STATE_SERVICE:
14874                    // These all are longer-term states, so pull them up to the top
14875                    // of the background states, but not all the way to the top state.
14876                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14877                    break;
14878                default:
14879                    // Otherwise, top is a better choice, so take it.
14880                    procState = ActivityManager.PROCESS_STATE_TOP;
14881                    break;
14882            }
14883        }
14884
14885        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14886            // This is a cached process, but with client activities.  Mark it so.
14887            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14888            app.adjType = "cch-client-act";
14889        }
14890
14891        if (adj == ProcessList.SERVICE_ADJ) {
14892            if (doingAll) {
14893                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14894                mNewNumServiceProcs++;
14895                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14896                if (!app.serviceb) {
14897                    // This service isn't far enough down on the LRU list to
14898                    // normally be a B service, but if we are low on RAM and it
14899                    // is large we want to force it down since we would prefer to
14900                    // keep launcher over it.
14901                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14902                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14903                        app.serviceHighRam = true;
14904                        app.serviceb = true;
14905                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14906                    } else {
14907                        mNewNumAServiceProcs++;
14908                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14909                    }
14910                } else {
14911                    app.serviceHighRam = false;
14912                }
14913            }
14914            if (app.serviceb) {
14915                adj = ProcessList.SERVICE_B_ADJ;
14916            }
14917        }
14918
14919        app.curRawAdj = adj;
14920
14921        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14922        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14923        if (adj > app.maxAdj) {
14924            adj = app.maxAdj;
14925            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14926                schedGroup = Process.THREAD_GROUP_DEFAULT;
14927            }
14928        }
14929        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14930            app.keeping = true;
14931        }
14932
14933        // Do final modification to adj.  Everything we do between here and applying
14934        // the final setAdj must be done in this function, because we will also use
14935        // it when computing the final cached adj later.  Note that we don't need to
14936        // worry about this for max adj above, since max adj will always be used to
14937        // keep it out of the cached vaues.
14938        adj = app.modifyRawOomAdj(adj);
14939
14940        app.curProcState = procState;
14941
14942        int importance = app.memImportance;
14943        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14944            app.curAdj = adj;
14945            app.curSchedGroup = schedGroup;
14946            if (!interesting) {
14947                // For this reporting, if there is not something explicitly
14948                // interesting in this process then we will push it to the
14949                // background importance.
14950                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14951            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14952                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14953            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14954                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14955            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14956                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14957            } else if (adj >= ProcessList.SERVICE_ADJ) {
14958                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14959            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14960                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14961            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14962                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14963            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14964                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14965            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14966                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14967            } else {
14968                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14969            }
14970        }
14971
14972        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14973        if (foregroundActivities != app.foregroundActivities) {
14974            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14975        }
14976        if (changes != 0) {
14977            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14978            app.memImportance = importance;
14979            app.foregroundActivities = foregroundActivities;
14980            int i = mPendingProcessChanges.size()-1;
14981            ProcessChangeItem item = null;
14982            while (i >= 0) {
14983                item = mPendingProcessChanges.get(i);
14984                if (item.pid == app.pid) {
14985                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14986                    break;
14987                }
14988                i--;
14989            }
14990            if (i < 0) {
14991                // No existing item in pending changes; need a new one.
14992                final int NA = mAvailProcessChanges.size();
14993                if (NA > 0) {
14994                    item = mAvailProcessChanges.remove(NA-1);
14995                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14996                } else {
14997                    item = new ProcessChangeItem();
14998                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14999                }
15000                item.changes = 0;
15001                item.pid = app.pid;
15002                item.uid = app.info.uid;
15003                if (mPendingProcessChanges.size() == 0) {
15004                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15005                            "*** Enqueueing dispatch processes changed!");
15006                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15007                }
15008                mPendingProcessChanges.add(item);
15009            }
15010            item.changes |= changes;
15011            item.importance = importance;
15012            item.foregroundActivities = foregroundActivities;
15013            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
15014                    + Integer.toHexString(System.identityHashCode(item))
15015                    + " " + app.toShortString() + ": changes=" + item.changes
15016                    + " importance=" + item.importance
15017                    + " foreground=" + item.foregroundActivities
15018                    + " type=" + app.adjType + " source=" + app.adjSource
15019                    + " target=" + app.adjTarget);
15020        }
15021
15022        return app.curRawAdj;
15023    }
15024
15025    /**
15026     * Schedule PSS collection of a process.
15027     */
15028    void requestPssLocked(ProcessRecord proc, int procState) {
15029        if (mPendingPssProcesses.contains(proc)) {
15030            return;
15031        }
15032        if (mPendingPssProcesses.size() == 0) {
15033            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15034        }
15035        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15036        proc.pssProcState = procState;
15037        mPendingPssProcesses.add(proc);
15038    }
15039
15040    /**
15041     * Schedule PSS collection of all processes.
15042     */
15043    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15044        if (!always) {
15045            if (now < (mLastFullPssTime +
15046                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15047                return;
15048            }
15049        }
15050        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15051        mLastFullPssTime = now;
15052        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15053        mPendingPssProcesses.clear();
15054        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15055            ProcessRecord app = mLruProcesses.get(i);
15056            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15057                app.pssProcState = app.setProcState;
15058                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15059                        mSleeping, now);
15060                mPendingPssProcesses.add(app);
15061            }
15062        }
15063        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15064    }
15065
15066    /**
15067     * Ask a given process to GC right now.
15068     */
15069    final void performAppGcLocked(ProcessRecord app) {
15070        try {
15071            app.lastRequestedGc = SystemClock.uptimeMillis();
15072            if (app.thread != null) {
15073                if (app.reportLowMemory) {
15074                    app.reportLowMemory = false;
15075                    app.thread.scheduleLowMemory();
15076                } else {
15077                    app.thread.processInBackground();
15078                }
15079            }
15080        } catch (Exception e) {
15081            // whatever.
15082        }
15083    }
15084
15085    /**
15086     * Returns true if things are idle enough to perform GCs.
15087     */
15088    private final boolean canGcNowLocked() {
15089        boolean processingBroadcasts = false;
15090        for (BroadcastQueue q : mBroadcastQueues) {
15091            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15092                processingBroadcasts = true;
15093            }
15094        }
15095        return !processingBroadcasts
15096                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15097    }
15098
15099    /**
15100     * Perform GCs on all processes that are waiting for it, but only
15101     * if things are idle.
15102     */
15103    final void performAppGcsLocked() {
15104        final int N = mProcessesToGc.size();
15105        if (N <= 0) {
15106            return;
15107        }
15108        if (canGcNowLocked()) {
15109            while (mProcessesToGc.size() > 0) {
15110                ProcessRecord proc = mProcessesToGc.remove(0);
15111                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15112                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15113                            <= SystemClock.uptimeMillis()) {
15114                        // To avoid spamming the system, we will GC processes one
15115                        // at a time, waiting a few seconds between each.
15116                        performAppGcLocked(proc);
15117                        scheduleAppGcsLocked();
15118                        return;
15119                    } else {
15120                        // It hasn't been long enough since we last GCed this
15121                        // process...  put it in the list to wait for its time.
15122                        addProcessToGcListLocked(proc);
15123                        break;
15124                    }
15125                }
15126            }
15127
15128            scheduleAppGcsLocked();
15129        }
15130    }
15131
15132    /**
15133     * If all looks good, perform GCs on all processes waiting for them.
15134     */
15135    final void performAppGcsIfAppropriateLocked() {
15136        if (canGcNowLocked()) {
15137            performAppGcsLocked();
15138            return;
15139        }
15140        // Still not idle, wait some more.
15141        scheduleAppGcsLocked();
15142    }
15143
15144    /**
15145     * Schedule the execution of all pending app GCs.
15146     */
15147    final void scheduleAppGcsLocked() {
15148        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15149
15150        if (mProcessesToGc.size() > 0) {
15151            // Schedule a GC for the time to the next process.
15152            ProcessRecord proc = mProcessesToGc.get(0);
15153            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15154
15155            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15156            long now = SystemClock.uptimeMillis();
15157            if (when < (now+GC_TIMEOUT)) {
15158                when = now + GC_TIMEOUT;
15159            }
15160            mHandler.sendMessageAtTime(msg, when);
15161        }
15162    }
15163
15164    /**
15165     * Add a process to the array of processes waiting to be GCed.  Keeps the
15166     * list in sorted order by the last GC time.  The process can't already be
15167     * on the list.
15168     */
15169    final void addProcessToGcListLocked(ProcessRecord proc) {
15170        boolean added = false;
15171        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15172            if (mProcessesToGc.get(i).lastRequestedGc <
15173                    proc.lastRequestedGc) {
15174                added = true;
15175                mProcessesToGc.add(i+1, proc);
15176                break;
15177            }
15178        }
15179        if (!added) {
15180            mProcessesToGc.add(0, proc);
15181        }
15182    }
15183
15184    /**
15185     * Set up to ask a process to GC itself.  This will either do it
15186     * immediately, or put it on the list of processes to gc the next
15187     * time things are idle.
15188     */
15189    final void scheduleAppGcLocked(ProcessRecord app) {
15190        long now = SystemClock.uptimeMillis();
15191        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15192            return;
15193        }
15194        if (!mProcessesToGc.contains(app)) {
15195            addProcessToGcListLocked(app);
15196            scheduleAppGcsLocked();
15197        }
15198    }
15199
15200    final void checkExcessivePowerUsageLocked(boolean doKills) {
15201        updateCpuStatsNow();
15202
15203        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15204        boolean doWakeKills = doKills;
15205        boolean doCpuKills = doKills;
15206        if (mLastPowerCheckRealtime == 0) {
15207            doWakeKills = false;
15208        }
15209        if (mLastPowerCheckUptime == 0) {
15210            doCpuKills = false;
15211        }
15212        if (stats.isScreenOn()) {
15213            doWakeKills = false;
15214        }
15215        final long curRealtime = SystemClock.elapsedRealtime();
15216        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15217        final long curUptime = SystemClock.uptimeMillis();
15218        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15219        mLastPowerCheckRealtime = curRealtime;
15220        mLastPowerCheckUptime = curUptime;
15221        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15222            doWakeKills = false;
15223        }
15224        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15225            doCpuKills = false;
15226        }
15227        int i = mLruProcesses.size();
15228        while (i > 0) {
15229            i--;
15230            ProcessRecord app = mLruProcesses.get(i);
15231            if (!app.keeping) {
15232                long wtime;
15233                synchronized (stats) {
15234                    wtime = stats.getProcessWakeTime(app.info.uid,
15235                            app.pid, curRealtime);
15236                }
15237                long wtimeUsed = wtime - app.lastWakeTime;
15238                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15239                if (DEBUG_POWER) {
15240                    StringBuilder sb = new StringBuilder(128);
15241                    sb.append("Wake for ");
15242                    app.toShortString(sb);
15243                    sb.append(": over ");
15244                    TimeUtils.formatDuration(realtimeSince, sb);
15245                    sb.append(" used ");
15246                    TimeUtils.formatDuration(wtimeUsed, sb);
15247                    sb.append(" (");
15248                    sb.append((wtimeUsed*100)/realtimeSince);
15249                    sb.append("%)");
15250                    Slog.i(TAG, sb.toString());
15251                    sb.setLength(0);
15252                    sb.append("CPU for ");
15253                    app.toShortString(sb);
15254                    sb.append(": over ");
15255                    TimeUtils.formatDuration(uptimeSince, sb);
15256                    sb.append(" used ");
15257                    TimeUtils.formatDuration(cputimeUsed, sb);
15258                    sb.append(" (");
15259                    sb.append((cputimeUsed*100)/uptimeSince);
15260                    sb.append("%)");
15261                    Slog.i(TAG, sb.toString());
15262                }
15263                // If a process has held a wake lock for more
15264                // than 50% of the time during this period,
15265                // that sounds bad.  Kill!
15266                if (doWakeKills && realtimeSince > 0
15267                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15268                    synchronized (stats) {
15269                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15270                                realtimeSince, wtimeUsed);
15271                    }
15272                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15273                            + " during " + realtimeSince);
15274                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15275                } else if (doCpuKills && uptimeSince > 0
15276                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15277                    synchronized (stats) {
15278                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15279                                uptimeSince, cputimeUsed);
15280                    }
15281                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15282                            + " during " + uptimeSince);
15283                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15284                } else {
15285                    app.lastWakeTime = wtime;
15286                    app.lastCpuTime = app.curCpuTime;
15287                }
15288            }
15289        }
15290    }
15291
15292    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15293            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15294        boolean success = true;
15295
15296        if (app.curRawAdj != app.setRawAdj) {
15297            if (wasKeeping && !app.keeping) {
15298                // This app is no longer something we want to keep.  Note
15299                // its current wake lock time to later know to kill it if
15300                // it is not behaving well.
15301                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15302                synchronized (stats) {
15303                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15304                            app.pid, SystemClock.elapsedRealtime());
15305                }
15306                app.lastCpuTime = app.curCpuTime;
15307            }
15308
15309            app.setRawAdj = app.curRawAdj;
15310        }
15311
15312        if (app.curAdj != app.setAdj) {
15313            ProcessList.setOomAdj(app.pid, app.curAdj);
15314            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15315                TAG, "Set " + app.pid + " " + app.processName +
15316                " adj " + app.curAdj + ": " + app.adjType);
15317            app.setAdj = app.curAdj;
15318        }
15319
15320        if (app.setSchedGroup != app.curSchedGroup) {
15321            app.setSchedGroup = app.curSchedGroup;
15322            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15323                    "Setting process group of " + app.processName
15324                    + " to " + app.curSchedGroup);
15325            if (app.waitingToKill != null &&
15326                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15327                killUnneededProcessLocked(app, app.waitingToKill);
15328                success = false;
15329            } else {
15330                if (true) {
15331                    long oldId = Binder.clearCallingIdentity();
15332                    try {
15333                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15334                    } catch (Exception e) {
15335                        Slog.w(TAG, "Failed setting process group of " + app.pid
15336                                + " to " + app.curSchedGroup);
15337                        e.printStackTrace();
15338                    } finally {
15339                        Binder.restoreCallingIdentity(oldId);
15340                    }
15341                } else {
15342                    if (app.thread != null) {
15343                        try {
15344                            app.thread.setSchedulingGroup(app.curSchedGroup);
15345                        } catch (RemoteException e) {
15346                        }
15347                    }
15348                }
15349                Process.setSwappiness(app.pid,
15350                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15351            }
15352        }
15353        if (app.repProcState != app.curProcState) {
15354            app.repProcState = app.curProcState;
15355            if (!reportingProcessState && app.thread != null) {
15356                try {
15357                    if (false) {
15358                        //RuntimeException h = new RuntimeException("here");
15359                        Slog.i(TAG, "Sending new process state " + app.repProcState
15360                                + " to " + app /*, h*/);
15361                    }
15362                    app.thread.setProcessState(app.repProcState);
15363                } catch (RemoteException e) {
15364                }
15365            }
15366        }
15367        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15368                app.setProcState)) {
15369            app.lastStateTime = now;
15370            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15371                    mSleeping, now);
15372            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15373                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15374                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15375                    + (app.nextPssTime-now) + ": " + app);
15376        } else {
15377            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15378                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15379                requestPssLocked(app, app.setProcState);
15380                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15381                        mSleeping, now);
15382            } else if (false && DEBUG_PSS) {
15383                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15384            }
15385        }
15386        if (app.setProcState != app.curProcState) {
15387            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15388                    "Proc state change of " + app.processName
15389                    + " to " + app.curProcState);
15390            app.setProcState = app.curProcState;
15391            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15392                app.notCachedSinceIdle = false;
15393            }
15394            if (!doingAll) {
15395                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15396            } else {
15397                app.procStateChanged = true;
15398            }
15399        }
15400        return success;
15401    }
15402
15403    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15404        if (proc.thread != null && proc.baseProcessTracker != null) {
15405            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15406        }
15407    }
15408
15409    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15410            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15411        if (app.thread == null) {
15412            return false;
15413        }
15414
15415        final boolean wasKeeping = app.keeping;
15416
15417        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15418
15419        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15420                reportingProcessState, now);
15421    }
15422
15423    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15424            boolean oomAdj) {
15425        if (isForeground != proc.foregroundServices) {
15426            proc.foregroundServices = isForeground;
15427            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15428                    proc.info.uid);
15429            if (isForeground) {
15430                if (curProcs == null) {
15431                    curProcs = new ArrayList<ProcessRecord>();
15432                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15433                }
15434                if (!curProcs.contains(proc)) {
15435                    curProcs.add(proc);
15436                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15437                            proc.info.packageName, proc.info.uid);
15438                }
15439            } else {
15440                if (curProcs != null) {
15441                    if (curProcs.remove(proc)) {
15442                        mBatteryStatsService.noteEvent(
15443                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15444                                proc.info.packageName, proc.info.uid);
15445                        if (curProcs.size() <= 0) {
15446                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15447                        }
15448                    }
15449                }
15450            }
15451            if (oomAdj) {
15452                updateOomAdjLocked();
15453            }
15454        }
15455    }
15456
15457    private final ActivityRecord resumedAppLocked() {
15458        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15459        String pkg;
15460        int uid;
15461        if (act != null) {
15462            pkg = act.packageName;
15463            uid = act.info.applicationInfo.uid;
15464        } else {
15465            pkg = null;
15466            uid = -1;
15467        }
15468        // Has the UID or resumed package name changed?
15469        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15470                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15471            if (mCurResumedPackage != null) {
15472                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15473                        mCurResumedPackage, mCurResumedUid);
15474            }
15475            mCurResumedPackage = pkg;
15476            mCurResumedUid = uid;
15477            if (mCurResumedPackage != null) {
15478                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15479                        mCurResumedPackage, mCurResumedUid);
15480            }
15481        }
15482        return act;
15483    }
15484
15485    final boolean updateOomAdjLocked(ProcessRecord app) {
15486        return updateOomAdjLocked(app, false);
15487    }
15488
15489    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15490        final ActivityRecord TOP_ACT = resumedAppLocked();
15491        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15492        final boolean wasCached = app.cached;
15493
15494        mAdjSeq++;
15495
15496        // This is the desired cached adjusment we want to tell it to use.
15497        // If our app is currently cached, we know it, and that is it.  Otherwise,
15498        // we don't know it yet, and it needs to now be cached we will then
15499        // need to do a complete oom adj.
15500        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15501                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15502        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15503                SystemClock.uptimeMillis());
15504        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15505            // Changed to/from cached state, so apps after it in the LRU
15506            // list may also be changed.
15507            updateOomAdjLocked();
15508        }
15509        return success;
15510    }
15511
15512    final void updateOomAdjLocked() {
15513        final ActivityRecord TOP_ACT = resumedAppLocked();
15514        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15515        final long now = SystemClock.uptimeMillis();
15516        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15517        final int N = mLruProcesses.size();
15518
15519        if (false) {
15520            RuntimeException e = new RuntimeException();
15521            e.fillInStackTrace();
15522            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15523        }
15524
15525        mAdjSeq++;
15526        mNewNumServiceProcs = 0;
15527        mNewNumAServiceProcs = 0;
15528
15529        final int emptyProcessLimit;
15530        final int cachedProcessLimit;
15531        if (mProcessLimit <= 0) {
15532            emptyProcessLimit = cachedProcessLimit = 0;
15533        } else if (mProcessLimit == 1) {
15534            emptyProcessLimit = 1;
15535            cachedProcessLimit = 0;
15536        } else {
15537            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15538            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15539        }
15540
15541        // Let's determine how many processes we have running vs.
15542        // how many slots we have for background processes; we may want
15543        // to put multiple processes in a slot of there are enough of
15544        // them.
15545        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15546                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15547        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15548        if (numEmptyProcs > cachedProcessLimit) {
15549            // If there are more empty processes than our limit on cached
15550            // processes, then use the cached process limit for the factor.
15551            // This ensures that the really old empty processes get pushed
15552            // down to the bottom, so if we are running low on memory we will
15553            // have a better chance at keeping around more cached processes
15554            // instead of a gazillion empty processes.
15555            numEmptyProcs = cachedProcessLimit;
15556        }
15557        int emptyFactor = numEmptyProcs/numSlots;
15558        if (emptyFactor < 1) emptyFactor = 1;
15559        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15560        if (cachedFactor < 1) cachedFactor = 1;
15561        int stepCached = 0;
15562        int stepEmpty = 0;
15563        int numCached = 0;
15564        int numEmpty = 0;
15565        int numTrimming = 0;
15566
15567        mNumNonCachedProcs = 0;
15568        mNumCachedHiddenProcs = 0;
15569
15570        // First update the OOM adjustment for each of the
15571        // application processes based on their current state.
15572        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15573        int nextCachedAdj = curCachedAdj+1;
15574        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15575        int nextEmptyAdj = curEmptyAdj+2;
15576        for (int i=N-1; i>=0; i--) {
15577            ProcessRecord app = mLruProcesses.get(i);
15578            if (!app.killedByAm && app.thread != null) {
15579                app.procStateChanged = false;
15580                final boolean wasKeeping = app.keeping;
15581                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15582
15583                // If we haven't yet assigned the final cached adj
15584                // to the process, do that now.
15585                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15586                    switch (app.curProcState) {
15587                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15588                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15589                            // This process is a cached process holding activities...
15590                            // assign it the next cached value for that type, and then
15591                            // step that cached level.
15592                            app.curRawAdj = curCachedAdj;
15593                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15594                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15595                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15596                                    + ")");
15597                            if (curCachedAdj != nextCachedAdj) {
15598                                stepCached++;
15599                                if (stepCached >= cachedFactor) {
15600                                    stepCached = 0;
15601                                    curCachedAdj = nextCachedAdj;
15602                                    nextCachedAdj += 2;
15603                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15604                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15605                                    }
15606                                }
15607                            }
15608                            break;
15609                        default:
15610                            // For everything else, assign next empty cached process
15611                            // level and bump that up.  Note that this means that
15612                            // long-running services that have dropped down to the
15613                            // cached level will be treated as empty (since their process
15614                            // state is still as a service), which is what we want.
15615                            app.curRawAdj = curEmptyAdj;
15616                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15617                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15618                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15619                                    + ")");
15620                            if (curEmptyAdj != nextEmptyAdj) {
15621                                stepEmpty++;
15622                                if (stepEmpty >= emptyFactor) {
15623                                    stepEmpty = 0;
15624                                    curEmptyAdj = nextEmptyAdj;
15625                                    nextEmptyAdj += 2;
15626                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15627                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15628                                    }
15629                                }
15630                            }
15631                            break;
15632                    }
15633                }
15634
15635                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15636
15637                // Count the number of process types.
15638                switch (app.curProcState) {
15639                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15640                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15641                        mNumCachedHiddenProcs++;
15642                        numCached++;
15643                        if (numCached > cachedProcessLimit) {
15644                            killUnneededProcessLocked(app, "cached #" + numCached);
15645                        }
15646                        break;
15647                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15648                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15649                                && app.lastActivityTime < oldTime) {
15650                            killUnneededProcessLocked(app, "empty for "
15651                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15652                                    / 1000) + "s");
15653                        } else {
15654                            numEmpty++;
15655                            if (numEmpty > emptyProcessLimit) {
15656                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15657                            }
15658                        }
15659                        break;
15660                    default:
15661                        mNumNonCachedProcs++;
15662                        break;
15663                }
15664
15665                if (app.isolated && app.services.size() <= 0) {
15666                    // If this is an isolated process, and there are no
15667                    // services running in it, then the process is no longer
15668                    // needed.  We agressively kill these because we can by
15669                    // definition not re-use the same process again, and it is
15670                    // good to avoid having whatever code was running in them
15671                    // left sitting around after no longer needed.
15672                    killUnneededProcessLocked(app, "isolated not needed");
15673                }
15674
15675                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15676                        && !app.killedByAm) {
15677                    numTrimming++;
15678                }
15679            }
15680        }
15681
15682        mNumServiceProcs = mNewNumServiceProcs;
15683
15684        // Now determine the memory trimming level of background processes.
15685        // Unfortunately we need to start at the back of the list to do this
15686        // properly.  We only do this if the number of background apps we
15687        // are managing to keep around is less than half the maximum we desire;
15688        // if we are keeping a good number around, we'll let them use whatever
15689        // memory they want.
15690        final int numCachedAndEmpty = numCached + numEmpty;
15691        int memFactor;
15692        if (numCached <= ProcessList.TRIM_CACHED_APPS
15693                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15694            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15695                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15696            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15697                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15698            } else {
15699                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15700            }
15701        } else {
15702            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15703        }
15704        // We always allow the memory level to go up (better).  We only allow it to go
15705        // down if we are in a state where that is allowed, *and* the total number of processes
15706        // has gone down since last time.
15707        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15708                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15709                + " last=" + mLastNumProcesses);
15710        if (memFactor > mLastMemoryLevel) {
15711            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15712                memFactor = mLastMemoryLevel;
15713                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15714            }
15715        }
15716        mLastMemoryLevel = memFactor;
15717        mLastNumProcesses = mLruProcesses.size();
15718        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15719        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15720        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15721            if (mLowRamStartTime == 0) {
15722                mLowRamStartTime = now;
15723            }
15724            int step = 0;
15725            int fgTrimLevel;
15726            switch (memFactor) {
15727                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15728                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15729                    break;
15730                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15731                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15732                    break;
15733                default:
15734                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15735                    break;
15736            }
15737            int factor = numTrimming/3;
15738            int minFactor = 2;
15739            if (mHomeProcess != null) minFactor++;
15740            if (mPreviousProcess != null) minFactor++;
15741            if (factor < minFactor) factor = minFactor;
15742            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15743            for (int i=N-1; i>=0; i--) {
15744                ProcessRecord app = mLruProcesses.get(i);
15745                if (allChanged || app.procStateChanged) {
15746                    setProcessTrackerState(app, trackerMemFactor, now);
15747                    app.procStateChanged = false;
15748                }
15749                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15750                        && !app.killedByAm) {
15751                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15752                        try {
15753                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15754                                    "Trimming memory of " + app.processName
15755                                    + " to " + curLevel);
15756                            app.thread.scheduleTrimMemory(curLevel);
15757                        } catch (RemoteException e) {
15758                        }
15759                        if (false) {
15760                            // For now we won't do this; our memory trimming seems
15761                            // to be good enough at this point that destroying
15762                            // activities causes more harm than good.
15763                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15764                                    && app != mHomeProcess && app != mPreviousProcess) {
15765                                // Need to do this on its own message because the stack may not
15766                                // be in a consistent state at this point.
15767                                // For these apps we will also finish their activities
15768                                // to help them free memory.
15769                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15770                            }
15771                        }
15772                    }
15773                    app.trimMemoryLevel = curLevel;
15774                    step++;
15775                    if (step >= factor) {
15776                        step = 0;
15777                        switch (curLevel) {
15778                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15779                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15780                                break;
15781                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15782                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15783                                break;
15784                        }
15785                    }
15786                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15787                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15788                            && app.thread != null) {
15789                        try {
15790                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15791                                    "Trimming memory of heavy-weight " + app.processName
15792                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15793                            app.thread.scheduleTrimMemory(
15794                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15795                        } catch (RemoteException e) {
15796                        }
15797                    }
15798                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15799                } else {
15800                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15801                            || app.systemNoUi) && app.pendingUiClean) {
15802                        // If this application is now in the background and it
15803                        // had done UI, then give it the special trim level to
15804                        // have it free UI resources.
15805                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15806                        if (app.trimMemoryLevel < level && app.thread != null) {
15807                            try {
15808                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15809                                        "Trimming memory of bg-ui " + app.processName
15810                                        + " to " + level);
15811                                app.thread.scheduleTrimMemory(level);
15812                            } catch (RemoteException e) {
15813                            }
15814                        }
15815                        app.pendingUiClean = false;
15816                    }
15817                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15818                        try {
15819                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15820                                    "Trimming memory of fg " + app.processName
15821                                    + " to " + fgTrimLevel);
15822                            app.thread.scheduleTrimMemory(fgTrimLevel);
15823                        } catch (RemoteException e) {
15824                        }
15825                    }
15826                    app.trimMemoryLevel = fgTrimLevel;
15827                }
15828            }
15829        } else {
15830            if (mLowRamStartTime != 0) {
15831                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15832                mLowRamStartTime = 0;
15833            }
15834            for (int i=N-1; i>=0; i--) {
15835                ProcessRecord app = mLruProcesses.get(i);
15836                if (allChanged || app.procStateChanged) {
15837                    setProcessTrackerState(app, trackerMemFactor, now);
15838                    app.procStateChanged = false;
15839                }
15840                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15841                        || app.systemNoUi) && app.pendingUiClean) {
15842                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15843                            && app.thread != null) {
15844                        try {
15845                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15846                                    "Trimming memory of ui hidden " + app.processName
15847                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15848                            app.thread.scheduleTrimMemory(
15849                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15850                        } catch (RemoteException e) {
15851                        }
15852                    }
15853                    app.pendingUiClean = false;
15854                }
15855                app.trimMemoryLevel = 0;
15856            }
15857        }
15858
15859        if (mAlwaysFinishActivities) {
15860            // Need to do this on its own message because the stack may not
15861            // be in a consistent state at this point.
15862            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15863        }
15864
15865        if (allChanged) {
15866            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15867        }
15868
15869        if (mProcessStats.shouldWriteNowLocked(now)) {
15870            mHandler.post(new Runnable() {
15871                @Override public void run() {
15872                    synchronized (ActivityManagerService.this) {
15873                        mProcessStats.writeStateAsyncLocked();
15874                    }
15875                }
15876            });
15877        }
15878
15879        if (DEBUG_OOM_ADJ) {
15880            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15881        }
15882    }
15883
15884    final void trimApplications() {
15885        synchronized (this) {
15886            int i;
15887
15888            // First remove any unused application processes whose package
15889            // has been removed.
15890            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15891                final ProcessRecord app = mRemovedProcesses.get(i);
15892                if (app.activities.size() == 0
15893                        && app.curReceiver == null && app.services.size() == 0) {
15894                    Slog.i(
15895                        TAG, "Exiting empty application process "
15896                        + app.processName + " ("
15897                        + (app.thread != null ? app.thread.asBinder() : null)
15898                        + ")\n");
15899                    if (app.pid > 0 && app.pid != MY_PID) {
15900                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15901                                app.processName, app.setAdj, "empty");
15902                        app.killedByAm = true;
15903                        Process.killProcessQuiet(app.pid);
15904                    } else {
15905                        try {
15906                            app.thread.scheduleExit();
15907                        } catch (Exception e) {
15908                            // Ignore exceptions.
15909                        }
15910                    }
15911                    cleanUpApplicationRecordLocked(app, false, true, -1);
15912                    mRemovedProcesses.remove(i);
15913
15914                    if (app.persistent) {
15915                        if (app.persistent) {
15916                            addAppLocked(app.info, false);
15917                        }
15918                    }
15919                }
15920            }
15921
15922            // Now update the oom adj for all processes.
15923            updateOomAdjLocked();
15924        }
15925    }
15926
15927    /** This method sends the specified signal to each of the persistent apps */
15928    public void signalPersistentProcesses(int sig) throws RemoteException {
15929        if (sig != Process.SIGNAL_USR1) {
15930            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15931        }
15932
15933        synchronized (this) {
15934            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15935                    != PackageManager.PERMISSION_GRANTED) {
15936                throw new SecurityException("Requires permission "
15937                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15938            }
15939
15940            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15941                ProcessRecord r = mLruProcesses.get(i);
15942                if (r.thread != null && r.persistent) {
15943                    Process.sendSignal(r.pid, sig);
15944                }
15945            }
15946        }
15947    }
15948
15949    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15950        if (proc == null || proc == mProfileProc) {
15951            proc = mProfileProc;
15952            path = mProfileFile;
15953            profileType = mProfileType;
15954            clearProfilerLocked();
15955        }
15956        if (proc == null) {
15957            return;
15958        }
15959        try {
15960            proc.thread.profilerControl(false, path, null, profileType);
15961        } catch (RemoteException e) {
15962            throw new IllegalStateException("Process disappeared");
15963        }
15964    }
15965
15966    private void clearProfilerLocked() {
15967        if (mProfileFd != null) {
15968            try {
15969                mProfileFd.close();
15970            } catch (IOException e) {
15971            }
15972        }
15973        mProfileApp = null;
15974        mProfileProc = null;
15975        mProfileFile = null;
15976        mProfileType = 0;
15977        mAutoStopProfiler = false;
15978    }
15979
15980    public boolean profileControl(String process, int userId, boolean start,
15981            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15982
15983        try {
15984            synchronized (this) {
15985                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15986                // its own permission.
15987                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15988                        != PackageManager.PERMISSION_GRANTED) {
15989                    throw new SecurityException("Requires permission "
15990                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15991                }
15992
15993                if (start && fd == null) {
15994                    throw new IllegalArgumentException("null fd");
15995                }
15996
15997                ProcessRecord proc = null;
15998                if (process != null) {
15999                    proc = findProcessLocked(process, userId, "profileControl");
16000                }
16001
16002                if (start && (proc == null || proc.thread == null)) {
16003                    throw new IllegalArgumentException("Unknown process: " + process);
16004                }
16005
16006                if (start) {
16007                    stopProfilerLocked(null, null, 0);
16008                    setProfileApp(proc.info, proc.processName, path, fd, false);
16009                    mProfileProc = proc;
16010                    mProfileType = profileType;
16011                    try {
16012                        fd = fd.dup();
16013                    } catch (IOException e) {
16014                        fd = null;
16015                    }
16016                    proc.thread.profilerControl(start, path, fd, profileType);
16017                    fd = null;
16018                    mProfileFd = null;
16019                } else {
16020                    stopProfilerLocked(proc, path, profileType);
16021                    if (fd != null) {
16022                        try {
16023                            fd.close();
16024                        } catch (IOException e) {
16025                        }
16026                    }
16027                }
16028
16029                return true;
16030            }
16031        } catch (RemoteException e) {
16032            throw new IllegalStateException("Process disappeared");
16033        } finally {
16034            if (fd != null) {
16035                try {
16036                    fd.close();
16037                } catch (IOException e) {
16038                }
16039            }
16040        }
16041    }
16042
16043    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16044        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16045                userId, true, true, callName, null);
16046        ProcessRecord proc = null;
16047        try {
16048            int pid = Integer.parseInt(process);
16049            synchronized (mPidsSelfLocked) {
16050                proc = mPidsSelfLocked.get(pid);
16051            }
16052        } catch (NumberFormatException e) {
16053        }
16054
16055        if (proc == null) {
16056            ArrayMap<String, SparseArray<ProcessRecord>> all
16057                    = mProcessNames.getMap();
16058            SparseArray<ProcessRecord> procs = all.get(process);
16059            if (procs != null && procs.size() > 0) {
16060                proc = procs.valueAt(0);
16061                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16062                    for (int i=1; i<procs.size(); i++) {
16063                        ProcessRecord thisProc = procs.valueAt(i);
16064                        if (thisProc.userId == userId) {
16065                            proc = thisProc;
16066                            break;
16067                        }
16068                    }
16069                }
16070            }
16071        }
16072
16073        return proc;
16074    }
16075
16076    public boolean dumpHeap(String process, int userId, boolean managed,
16077            String path, ParcelFileDescriptor fd) throws RemoteException {
16078
16079        try {
16080            synchronized (this) {
16081                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16082                // its own permission (same as profileControl).
16083                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16084                        != PackageManager.PERMISSION_GRANTED) {
16085                    throw new SecurityException("Requires permission "
16086                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16087                }
16088
16089                if (fd == null) {
16090                    throw new IllegalArgumentException("null fd");
16091                }
16092
16093                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16094                if (proc == null || proc.thread == null) {
16095                    throw new IllegalArgumentException("Unknown process: " + process);
16096                }
16097
16098                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16099                if (!isDebuggable) {
16100                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16101                        throw new SecurityException("Process not debuggable: " + proc);
16102                    }
16103                }
16104
16105                proc.thread.dumpHeap(managed, path, fd);
16106                fd = null;
16107                return true;
16108            }
16109        } catch (RemoteException e) {
16110            throw new IllegalStateException("Process disappeared");
16111        } finally {
16112            if (fd != null) {
16113                try {
16114                    fd.close();
16115                } catch (IOException e) {
16116                }
16117            }
16118        }
16119    }
16120
16121    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16122    public void monitor() {
16123        synchronized (this) { }
16124    }
16125
16126    void onCoreSettingsChange(Bundle settings) {
16127        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16128            ProcessRecord processRecord = mLruProcesses.get(i);
16129            try {
16130                if (processRecord.thread != null) {
16131                    processRecord.thread.setCoreSettings(settings);
16132                }
16133            } catch (RemoteException re) {
16134                /* ignore */
16135            }
16136        }
16137    }
16138
16139    // Multi-user methods
16140
16141    /**
16142     * Start user, if its not already running, but don't bring it to foreground.
16143     */
16144    @Override
16145    public boolean startUserInBackground(final int userId) {
16146        return startUser(userId, /* foreground */ false);
16147    }
16148
16149    /**
16150     * Refreshes the list of users related to the current user when either a
16151     * user switch happens or when a new related user is started in the
16152     * background.
16153     */
16154    private void updateRelatedUserIdsLocked() {
16155        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16156        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
16157        for (int i = 0; i < relatedUserIds.length; i++) {
16158            relatedUserIds[i] = relatedUsers.get(i).id;
16159        }
16160        mRelatedUserIds = relatedUserIds;
16161    }
16162
16163    @Override
16164    public boolean switchUser(final int userId) {
16165        return startUser(userId, /* foregound */ true);
16166    }
16167
16168    private boolean startUser(final int userId, boolean foreground) {
16169        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16170                != PackageManager.PERMISSION_GRANTED) {
16171            String msg = "Permission Denial: switchUser() from pid="
16172                    + Binder.getCallingPid()
16173                    + ", uid=" + Binder.getCallingUid()
16174                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16175            Slog.w(TAG, msg);
16176            throw new SecurityException(msg);
16177        }
16178
16179        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16180
16181        final long ident = Binder.clearCallingIdentity();
16182        try {
16183            synchronized (this) {
16184                final int oldUserId = mCurrentUserId;
16185                if (oldUserId == userId) {
16186                    return true;
16187                }
16188
16189                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16190                if (userInfo == null) {
16191                    Slog.w(TAG, "No user info for user #" + userId);
16192                    return false;
16193                }
16194
16195                if (foreground) {
16196                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16197                            R.anim.screen_user_enter);
16198                }
16199
16200                boolean needStart = false;
16201
16202                // If the user we are switching to is not currently started, then
16203                // we need to start it now.
16204                if (mStartedUsers.get(userId) == null) {
16205                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16206                    updateStartedUserArrayLocked();
16207                    needStart = true;
16208                }
16209
16210                final Integer userIdInt = Integer.valueOf(userId);
16211                mUserLru.remove(userIdInt);
16212                mUserLru.add(userIdInt);
16213
16214                if (foreground) {
16215                    mCurrentUserId = userId;
16216                    updateRelatedUserIdsLocked();
16217                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
16218                    // Once the internal notion of the active user has switched, we lock the device
16219                    // with the option to show the user switcher on the keyguard.
16220                    mWindowManager.lockNow(null);
16221                } else {
16222                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16223                    updateRelatedUserIdsLocked();
16224                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
16225                    mUserLru.remove(currentUserIdInt);
16226                    mUserLru.add(currentUserIdInt);
16227                }
16228
16229                final UserStartedState uss = mStartedUsers.get(userId);
16230
16231                // Make sure user is in the started state.  If it is currently
16232                // stopping, we need to knock that off.
16233                if (uss.mState == UserStartedState.STATE_STOPPING) {
16234                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16235                    // so we can just fairly silently bring the user back from
16236                    // the almost-dead.
16237                    uss.mState = UserStartedState.STATE_RUNNING;
16238                    updateStartedUserArrayLocked();
16239                    needStart = true;
16240                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16241                    // This means ACTION_SHUTDOWN has been sent, so we will
16242                    // need to treat this as a new boot of the user.
16243                    uss.mState = UserStartedState.STATE_BOOTING;
16244                    updateStartedUserArrayLocked();
16245                    needStart = true;
16246                }
16247
16248                if (foreground) {
16249                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16250                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16251                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16252                            oldUserId, userId, uss));
16253                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16254                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16255                }
16256
16257                if (needStart) {
16258                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16259                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16260                            | Intent.FLAG_RECEIVER_FOREGROUND);
16261                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16262                    broadcastIntentLocked(null, null, intent,
16263                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16264                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16265                }
16266
16267                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16268                    if (userId != 0) {
16269                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16270                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16271                        broadcastIntentLocked(null, null, intent, null,
16272                                new IIntentReceiver.Stub() {
16273                                    public void performReceive(Intent intent, int resultCode,
16274                                            String data, Bundle extras, boolean ordered,
16275                                            boolean sticky, int sendingUser) {
16276                                        userInitialized(uss, userId);
16277                                    }
16278                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16279                                true, false, MY_PID, Process.SYSTEM_UID,
16280                                userId);
16281                        uss.initializing = true;
16282                    } else {
16283                        getUserManagerLocked().makeInitialized(userInfo.id);
16284                    }
16285                }
16286
16287                if (foreground) {
16288                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16289                    if (homeInFront) {
16290                        startHomeActivityLocked(userId);
16291                    } else {
16292                        mStackSupervisor.resumeTopActivitiesLocked();
16293                    }
16294                    EventLogTags.writeAmSwitchUser(userId);
16295                    getUserManagerLocked().userForeground(userId);
16296                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16297                }
16298
16299                if (needStart) {
16300                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16301                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16302                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16303                    broadcastIntentLocked(null, null, intent,
16304                            null, new IIntentReceiver.Stub() {
16305                                @Override
16306                                public void performReceive(Intent intent, int resultCode, String data,
16307                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16308                                        throws RemoteException {
16309                                }
16310                            }, 0, null, null,
16311                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16312                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16313                }
16314            }
16315        } finally {
16316            Binder.restoreCallingIdentity(ident);
16317        }
16318
16319        return true;
16320    }
16321
16322    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16323        long ident = Binder.clearCallingIdentity();
16324        try {
16325            Intent intent;
16326            if (oldUserId >= 0) {
16327                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16328                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16329                        | Intent.FLAG_RECEIVER_FOREGROUND);
16330                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16331                broadcastIntentLocked(null, null, intent,
16332                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16333                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16334            }
16335            if (newUserId >= 0) {
16336                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16337                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16338                        | Intent.FLAG_RECEIVER_FOREGROUND);
16339                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16340                broadcastIntentLocked(null, null, intent,
16341                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16342                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16343                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16344                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16345                        | Intent.FLAG_RECEIVER_FOREGROUND);
16346                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16347                broadcastIntentLocked(null, null, intent,
16348                        null, null, 0, null, null,
16349                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16350                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16351            }
16352        } finally {
16353            Binder.restoreCallingIdentity(ident);
16354        }
16355    }
16356
16357    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16358            final int newUserId) {
16359        final int N = mUserSwitchObservers.beginBroadcast();
16360        if (N > 0) {
16361            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16362                int mCount = 0;
16363                @Override
16364                public void sendResult(Bundle data) throws RemoteException {
16365                    synchronized (ActivityManagerService.this) {
16366                        if (mCurUserSwitchCallback == this) {
16367                            mCount++;
16368                            if (mCount == N) {
16369                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16370                            }
16371                        }
16372                    }
16373                }
16374            };
16375            synchronized (this) {
16376                uss.switching = true;
16377                mCurUserSwitchCallback = callback;
16378            }
16379            for (int i=0; i<N; i++) {
16380                try {
16381                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16382                            newUserId, callback);
16383                } catch (RemoteException e) {
16384                }
16385            }
16386        } else {
16387            synchronized (this) {
16388                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16389            }
16390        }
16391        mUserSwitchObservers.finishBroadcast();
16392    }
16393
16394    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16395        synchronized (this) {
16396            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16397            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16398        }
16399    }
16400
16401    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16402        mCurUserSwitchCallback = null;
16403        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16404        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16405                oldUserId, newUserId, uss));
16406    }
16407
16408    void userInitialized(UserStartedState uss, int newUserId) {
16409        completeSwitchAndInitalize(uss, newUserId, true, false);
16410    }
16411
16412    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16413        completeSwitchAndInitalize(uss, newUserId, false, true);
16414    }
16415
16416    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16417            boolean clearInitializing, boolean clearSwitching) {
16418        boolean unfrozen = false;
16419        synchronized (this) {
16420            if (clearInitializing) {
16421                uss.initializing = false;
16422                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16423            }
16424            if (clearSwitching) {
16425                uss.switching = false;
16426            }
16427            if (!uss.switching && !uss.initializing) {
16428                mWindowManager.stopFreezingScreen();
16429                unfrozen = true;
16430            }
16431        }
16432        if (unfrozen) {
16433            final int N = mUserSwitchObservers.beginBroadcast();
16434            for (int i=0; i<N; i++) {
16435                try {
16436                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16437                } catch (RemoteException e) {
16438                }
16439            }
16440            mUserSwitchObservers.finishBroadcast();
16441        }
16442    }
16443
16444    void scheduleStartRelatedUsersLocked() {
16445        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16446            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16447                    DateUtils.SECOND_IN_MILLIS);
16448        }
16449    }
16450
16451    void startRelatedUsersLocked() {
16452        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16453        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16454        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16455        for (UserInfo relatedUser : relatedUsers) {
16456            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16457                toStart.add(relatedUser);
16458            }
16459        }
16460        final int n = toStart.size();
16461        int i = 0;
16462        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16463            startUserInBackground(toStart.get(i).id);
16464        }
16465        if (i < n) {
16466            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16467        }
16468    }
16469
16470    void finishUserSwitch(UserStartedState uss) {
16471        synchronized (this) {
16472            if (uss.mState == UserStartedState.STATE_BOOTING
16473                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16474                uss.mState = UserStartedState.STATE_RUNNING;
16475                final int userId = uss.mHandle.getIdentifier();
16476                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16477                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16478                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16479                broadcastIntentLocked(null, null, intent,
16480                        null, null, 0, null, null,
16481                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16482                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16483            }
16484
16485            startRelatedUsersLocked();
16486
16487            int num = mUserLru.size();
16488            int i = 0;
16489            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16490                Integer oldUserId = mUserLru.get(i);
16491                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16492                if (oldUss == null) {
16493                    // Shouldn't happen, but be sane if it does.
16494                    mUserLru.remove(i);
16495                    num--;
16496                    continue;
16497                }
16498                if (oldUss.mState == UserStartedState.STATE_STOPPING
16499                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16500                    // This user is already stopping, doesn't count.
16501                    num--;
16502                    i++;
16503                    continue;
16504                }
16505                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16506                    // Owner and current can't be stopped, but count as running.
16507                    i++;
16508                    continue;
16509                }
16510                // This is a user to be stopped.
16511                stopUserLocked(oldUserId, null);
16512                num--;
16513                i++;
16514            }
16515        }
16516    }
16517
16518    @Override
16519    public int stopUser(final int userId, final IStopUserCallback callback) {
16520        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16521                != PackageManager.PERMISSION_GRANTED) {
16522            String msg = "Permission Denial: switchUser() from pid="
16523                    + Binder.getCallingPid()
16524                    + ", uid=" + Binder.getCallingUid()
16525                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16526            Slog.w(TAG, msg);
16527            throw new SecurityException(msg);
16528        }
16529        if (userId <= 0) {
16530            throw new IllegalArgumentException("Can't stop primary user " + userId);
16531        }
16532        synchronized (this) {
16533            return stopUserLocked(userId, callback);
16534        }
16535    }
16536
16537    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16538        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16539        if (mCurrentUserId == userId) {
16540            return ActivityManager.USER_OP_IS_CURRENT;
16541        }
16542
16543        final UserStartedState uss = mStartedUsers.get(userId);
16544        if (uss == null) {
16545            // User is not started, nothing to do...  but we do need to
16546            // callback if requested.
16547            if (callback != null) {
16548                mHandler.post(new Runnable() {
16549                    @Override
16550                    public void run() {
16551                        try {
16552                            callback.userStopped(userId);
16553                        } catch (RemoteException e) {
16554                        }
16555                    }
16556                });
16557            }
16558            return ActivityManager.USER_OP_SUCCESS;
16559        }
16560
16561        if (callback != null) {
16562            uss.mStopCallbacks.add(callback);
16563        }
16564
16565        if (uss.mState != UserStartedState.STATE_STOPPING
16566                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16567            uss.mState = UserStartedState.STATE_STOPPING;
16568            updateStartedUserArrayLocked();
16569
16570            long ident = Binder.clearCallingIdentity();
16571            try {
16572                // We are going to broadcast ACTION_USER_STOPPING and then
16573                // once that is done send a final ACTION_SHUTDOWN and then
16574                // stop the user.
16575                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16576                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16577                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16578                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16579                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16580                // This is the result receiver for the final shutdown broadcast.
16581                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16582                    @Override
16583                    public void performReceive(Intent intent, int resultCode, String data,
16584                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16585                        finishUserStop(uss);
16586                    }
16587                };
16588                // This is the result receiver for the initial stopping broadcast.
16589                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16590                    @Override
16591                    public void performReceive(Intent intent, int resultCode, String data,
16592                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16593                        // On to the next.
16594                        synchronized (ActivityManagerService.this) {
16595                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16596                                // Whoops, we are being started back up.  Abort, abort!
16597                                return;
16598                            }
16599                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16600                        }
16601                        broadcastIntentLocked(null, null, shutdownIntent,
16602                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16603                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16604                    }
16605                };
16606                // Kick things off.
16607                broadcastIntentLocked(null, null, stoppingIntent,
16608                        null, stoppingReceiver, 0, null, null,
16609                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16610                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16611            } finally {
16612                Binder.restoreCallingIdentity(ident);
16613            }
16614        }
16615
16616        return ActivityManager.USER_OP_SUCCESS;
16617    }
16618
16619    void finishUserStop(UserStartedState uss) {
16620        final int userId = uss.mHandle.getIdentifier();
16621        boolean stopped;
16622        ArrayList<IStopUserCallback> callbacks;
16623        synchronized (this) {
16624            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16625            if (mStartedUsers.get(userId) != uss) {
16626                stopped = false;
16627            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16628                stopped = false;
16629            } else {
16630                stopped = true;
16631                // User can no longer run.
16632                mStartedUsers.remove(userId);
16633                mUserLru.remove(Integer.valueOf(userId));
16634                updateStartedUserArrayLocked();
16635
16636                // Clean up all state and processes associated with the user.
16637                // Kill all the processes for the user.
16638                forceStopUserLocked(userId, "finish user");
16639            }
16640        }
16641
16642        for (int i=0; i<callbacks.size(); i++) {
16643            try {
16644                if (stopped) callbacks.get(i).userStopped(userId);
16645                else callbacks.get(i).userStopAborted(userId);
16646            } catch (RemoteException e) {
16647            }
16648        }
16649
16650        mStackSupervisor.removeUserLocked(userId);
16651    }
16652
16653    @Override
16654    public UserInfo getCurrentUser() {
16655        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16656                != PackageManager.PERMISSION_GRANTED) && (
16657                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16658                != PackageManager.PERMISSION_GRANTED)) {
16659            String msg = "Permission Denial: getCurrentUser() from pid="
16660                    + Binder.getCallingPid()
16661                    + ", uid=" + Binder.getCallingUid()
16662                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16663            Slog.w(TAG, msg);
16664            throw new SecurityException(msg);
16665        }
16666        synchronized (this) {
16667            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16668        }
16669    }
16670
16671    int getCurrentUserIdLocked() {
16672        return mCurrentUserId;
16673    }
16674
16675    @Override
16676    public boolean isUserRunning(int userId, boolean orStopped) {
16677        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16678                != PackageManager.PERMISSION_GRANTED) {
16679            String msg = "Permission Denial: isUserRunning() from pid="
16680                    + Binder.getCallingPid()
16681                    + ", uid=" + Binder.getCallingUid()
16682                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16683            Slog.w(TAG, msg);
16684            throw new SecurityException(msg);
16685        }
16686        synchronized (this) {
16687            return isUserRunningLocked(userId, orStopped);
16688        }
16689    }
16690
16691    boolean isUserRunningLocked(int userId, boolean orStopped) {
16692        UserStartedState state = mStartedUsers.get(userId);
16693        if (state == null) {
16694            return false;
16695        }
16696        if (orStopped) {
16697            return true;
16698        }
16699        return state.mState != UserStartedState.STATE_STOPPING
16700                && state.mState != UserStartedState.STATE_SHUTDOWN;
16701    }
16702
16703    @Override
16704    public int[] getRunningUserIds() {
16705        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16706                != PackageManager.PERMISSION_GRANTED) {
16707            String msg = "Permission Denial: isUserRunning() from pid="
16708                    + Binder.getCallingPid()
16709                    + ", uid=" + Binder.getCallingUid()
16710                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16711            Slog.w(TAG, msg);
16712            throw new SecurityException(msg);
16713        }
16714        synchronized (this) {
16715            return mStartedUserArray;
16716        }
16717    }
16718
16719    private void updateStartedUserArrayLocked() {
16720        int num = 0;
16721        for (int i=0; i<mStartedUsers.size();  i++) {
16722            UserStartedState uss = mStartedUsers.valueAt(i);
16723            // This list does not include stopping users.
16724            if (uss.mState != UserStartedState.STATE_STOPPING
16725                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16726                num++;
16727            }
16728        }
16729        mStartedUserArray = new int[num];
16730        num = 0;
16731        for (int i=0; i<mStartedUsers.size();  i++) {
16732            UserStartedState uss = mStartedUsers.valueAt(i);
16733            if (uss.mState != UserStartedState.STATE_STOPPING
16734                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16735                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16736                num++;
16737            }
16738        }
16739    }
16740
16741    @Override
16742    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16743        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16744                != PackageManager.PERMISSION_GRANTED) {
16745            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16746                    + Binder.getCallingPid()
16747                    + ", uid=" + Binder.getCallingUid()
16748                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16749            Slog.w(TAG, msg);
16750            throw new SecurityException(msg);
16751        }
16752
16753        mUserSwitchObservers.register(observer);
16754    }
16755
16756    @Override
16757    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16758        mUserSwitchObservers.unregister(observer);
16759    }
16760
16761    private boolean userExists(int userId) {
16762        if (userId == 0) {
16763            return true;
16764        }
16765        UserManagerService ums = getUserManagerLocked();
16766        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16767    }
16768
16769    int[] getUsersLocked() {
16770        UserManagerService ums = getUserManagerLocked();
16771        return ums != null ? ums.getUserIds() : new int[] { 0 };
16772    }
16773
16774    UserManagerService getUserManagerLocked() {
16775        if (mUserManager == null) {
16776            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16777            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16778        }
16779        return mUserManager;
16780    }
16781
16782    private int applyUserId(int uid, int userId) {
16783        return UserHandle.getUid(userId, uid);
16784    }
16785
16786    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16787        if (info == null) return null;
16788        ApplicationInfo newInfo = new ApplicationInfo(info);
16789        newInfo.uid = applyUserId(info.uid, userId);
16790        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16791                + info.packageName;
16792        return newInfo;
16793    }
16794
16795    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16796        if (aInfo == null
16797                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16798            return aInfo;
16799        }
16800
16801        ActivityInfo info = new ActivityInfo(aInfo);
16802        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16803        return info;
16804    }
16805}
16806