ActivityManagerService.java revision ccb2a086fe0de77a4e3277454cb4a66f8e7dc57d
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    private UserManagerService mUserManager;
1019
1020    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1021        final ProcessRecord mApp;
1022        final int mPid;
1023        final IApplicationThread mAppThread;
1024
1025        AppDeathRecipient(ProcessRecord app, int pid,
1026                IApplicationThread thread) {
1027            if (localLOGV) Slog.v(
1028                TAG, "New death recipient " + this
1029                + " for thread " + thread.asBinder());
1030            mApp = app;
1031            mPid = pid;
1032            mAppThread = thread;
1033        }
1034
1035        @Override
1036        public void binderDied() {
1037            if (localLOGV) Slog.v(
1038                TAG, "Death received in " + this
1039                + " for thread " + mAppThread.asBinder());
1040            synchronized(ActivityManagerService.this) {
1041                appDiedLocked(mApp, mPid, mAppThread);
1042            }
1043        }
1044    }
1045
1046    static final int SHOW_ERROR_MSG = 1;
1047    static final int SHOW_NOT_RESPONDING_MSG = 2;
1048    static final int SHOW_FACTORY_ERROR_MSG = 3;
1049    static final int UPDATE_CONFIGURATION_MSG = 4;
1050    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1051    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1052    static final int SERVICE_TIMEOUT_MSG = 12;
1053    static final int UPDATE_TIME_ZONE = 13;
1054    static final int SHOW_UID_ERROR_MSG = 14;
1055    static final int IM_FEELING_LUCKY_MSG = 15;
1056    static final int PROC_START_TIMEOUT_MSG = 20;
1057    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1058    static final int KILL_APPLICATION_MSG = 22;
1059    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1060    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1061    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1062    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1063    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1064    static final int CLEAR_DNS_CACHE_MSG = 28;
1065    static final int UPDATE_HTTP_PROXY_MSG = 29;
1066    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1067    static final int DISPATCH_PROCESSES_CHANGED = 31;
1068    static final int DISPATCH_PROCESS_DIED = 32;
1069    static final int REPORT_MEM_USAGE_MSG = 33;
1070    static final int REPORT_USER_SWITCH_MSG = 34;
1071    static final int CONTINUE_USER_SWITCH_MSG = 35;
1072    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1073    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1074    static final int PERSIST_URI_GRANTS_MSG = 38;
1075    static final int REQUEST_ALL_PSS_MSG = 39;
1076    static final int START_RELATED_USERS_MSG = 40;
1077    static final int UPDATE_TIME = 41;
1078
1079    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1080    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1081    static final int FIRST_COMPAT_MODE_MSG = 300;
1082    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1083
1084    AlertDialog mUidAlert;
1085    CompatModeDialog mCompatModeDialog;
1086    long mLastMemUsageReportTime = 0;
1087
1088    /**
1089     * Flag whether the current user is a "monkey", i.e. whether
1090     * the UI is driven by a UI automation tool.
1091     */
1092    private boolean mUserIsMonkey;
1093
1094    final ServiceThread mHandlerThread;
1095    final MainHandler mHandler;
1096
1097    final class MainHandler extends Handler {
1098        public MainHandler(Looper looper) {
1099            super(looper, null, true);
1100        }
1101
1102        @Override
1103        public void handleMessage(Message msg) {
1104            switch (msg.what) {
1105            case SHOW_ERROR_MSG: {
1106                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1107                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1108                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1109                synchronized (ActivityManagerService.this) {
1110                    ProcessRecord proc = (ProcessRecord)data.get("app");
1111                    AppErrorResult res = (AppErrorResult) data.get("result");
1112                    if (proc != null && proc.crashDialog != null) {
1113                        Slog.e(TAG, "App already has crash dialog: " + proc);
1114                        if (res != null) {
1115                            res.set(0);
1116                        }
1117                        return;
1118                    }
1119                    if (!showBackground && UserHandle.getAppId(proc.uid)
1120                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1121                            && proc.pid != MY_PID) {
1122                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1123                        if (res != null) {
1124                            res.set(0);
1125                        }
1126                        return;
1127                    }
1128                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1129                        Dialog d = new AppErrorDialog(mContext,
1130                                ActivityManagerService.this, res, proc);
1131                        d.show();
1132                        proc.crashDialog = d;
1133                    } else {
1134                        // The device is asleep, so just pretend that the user
1135                        // saw a crash dialog and hit "force quit".
1136                        if (res != null) {
1137                            res.set(0);
1138                        }
1139                    }
1140                }
1141
1142                ensureBootCompleted();
1143            } break;
1144            case SHOW_NOT_RESPONDING_MSG: {
1145                synchronized (ActivityManagerService.this) {
1146                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1147                    ProcessRecord proc = (ProcessRecord)data.get("app");
1148                    if (proc != null && proc.anrDialog != null) {
1149                        Slog.e(TAG, "App already has anr dialog: " + proc);
1150                        return;
1151                    }
1152
1153                    Intent intent = new Intent("android.intent.action.ANR");
1154                    if (!mProcessesReady) {
1155                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1156                                | Intent.FLAG_RECEIVER_FOREGROUND);
1157                    }
1158                    broadcastIntentLocked(null, null, intent,
1159                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1160                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1161
1162                    if (mShowDialogs) {
1163                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1164                                mContext, proc, (ActivityRecord)data.get("activity"),
1165                                msg.arg1 != 0);
1166                        d.show();
1167                        proc.anrDialog = d;
1168                    } else {
1169                        // Just kill the app if there is no dialog to be shown.
1170                        killAppAtUsersRequest(proc, null);
1171                    }
1172                }
1173
1174                ensureBootCompleted();
1175            } break;
1176            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1177                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1178                synchronized (ActivityManagerService.this) {
1179                    ProcessRecord proc = (ProcessRecord) data.get("app");
1180                    if (proc == null) {
1181                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1182                        break;
1183                    }
1184                    if (proc.crashDialog != null) {
1185                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1186                        return;
1187                    }
1188                    AppErrorResult res = (AppErrorResult) data.get("result");
1189                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1190                        Dialog d = new StrictModeViolationDialog(mContext,
1191                                ActivityManagerService.this, res, proc);
1192                        d.show();
1193                        proc.crashDialog = d;
1194                    } else {
1195                        // The device is asleep, so just pretend that the user
1196                        // saw a crash dialog and hit "force quit".
1197                        res.set(0);
1198                    }
1199                }
1200                ensureBootCompleted();
1201            } break;
1202            case SHOW_FACTORY_ERROR_MSG: {
1203                Dialog d = new FactoryErrorDialog(
1204                    mContext, msg.getData().getCharSequence("msg"));
1205                d.show();
1206                ensureBootCompleted();
1207            } break;
1208            case UPDATE_CONFIGURATION_MSG: {
1209                final ContentResolver resolver = mContext.getContentResolver();
1210                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1211            } break;
1212            case GC_BACKGROUND_PROCESSES_MSG: {
1213                synchronized (ActivityManagerService.this) {
1214                    performAppGcsIfAppropriateLocked();
1215                }
1216            } break;
1217            case WAIT_FOR_DEBUGGER_MSG: {
1218                synchronized (ActivityManagerService.this) {
1219                    ProcessRecord app = (ProcessRecord)msg.obj;
1220                    if (msg.arg1 != 0) {
1221                        if (!app.waitedForDebugger) {
1222                            Dialog d = new AppWaitingForDebuggerDialog(
1223                                    ActivityManagerService.this,
1224                                    mContext, app);
1225                            app.waitDialog = d;
1226                            app.waitedForDebugger = true;
1227                            d.show();
1228                        }
1229                    } else {
1230                        if (app.waitDialog != null) {
1231                            app.waitDialog.dismiss();
1232                            app.waitDialog = null;
1233                        }
1234                    }
1235                }
1236            } break;
1237            case SERVICE_TIMEOUT_MSG: {
1238                if (mDidDexOpt) {
1239                    mDidDexOpt = false;
1240                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1241                    nmsg.obj = msg.obj;
1242                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1243                    return;
1244                }
1245                mServices.serviceTimeout((ProcessRecord)msg.obj);
1246            } break;
1247            case UPDATE_TIME_ZONE: {
1248                synchronized (ActivityManagerService.this) {
1249                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1250                        ProcessRecord r = mLruProcesses.get(i);
1251                        if (r.thread != null) {
1252                            try {
1253                                r.thread.updateTimeZone();
1254                            } catch (RemoteException ex) {
1255                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1256                            }
1257                        }
1258                    }
1259                }
1260            } break;
1261            case CLEAR_DNS_CACHE_MSG: {
1262                synchronized (ActivityManagerService.this) {
1263                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1264                        ProcessRecord r = mLruProcesses.get(i);
1265                        if (r.thread != null) {
1266                            try {
1267                                r.thread.clearDnsCache();
1268                            } catch (RemoteException ex) {
1269                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1270                            }
1271                        }
1272                    }
1273                }
1274            } break;
1275            case UPDATE_HTTP_PROXY_MSG: {
1276                ProxyProperties proxy = (ProxyProperties)msg.obj;
1277                String host = "";
1278                String port = "";
1279                String exclList = "";
1280                String pacFileUrl = null;
1281                if (proxy != null) {
1282                    host = proxy.getHost();
1283                    port = Integer.toString(proxy.getPort());
1284                    exclList = proxy.getExclusionList();
1285                    pacFileUrl = proxy.getPacFileUrl();
1286                }
1287                synchronized (ActivityManagerService.this) {
1288                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1289                        ProcessRecord r = mLruProcesses.get(i);
1290                        if (r.thread != null) {
1291                            try {
1292                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1293                            } catch (RemoteException ex) {
1294                                Slog.w(TAG, "Failed to update http proxy for: " +
1295                                        r.info.processName);
1296                            }
1297                        }
1298                    }
1299                }
1300            } break;
1301            case SHOW_UID_ERROR_MSG: {
1302                String title = "System UIDs Inconsistent";
1303                String text = "UIDs on the system are inconsistent, you need to wipe your"
1304                        + " data partition or your device will be unstable.";
1305                Log.e(TAG, title + ": " + text);
1306                if (mShowDialogs) {
1307                    // XXX This is a temporary dialog, no need to localize.
1308                    AlertDialog d = new BaseErrorDialog(mContext);
1309                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1310                    d.setCancelable(false);
1311                    d.setTitle(title);
1312                    d.setMessage(text);
1313                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1314                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1315                    mUidAlert = d;
1316                    d.show();
1317                }
1318            } break;
1319            case IM_FEELING_LUCKY_MSG: {
1320                if (mUidAlert != null) {
1321                    mUidAlert.dismiss();
1322                    mUidAlert = null;
1323                }
1324            } break;
1325            case PROC_START_TIMEOUT_MSG: {
1326                if (mDidDexOpt) {
1327                    mDidDexOpt = false;
1328                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1329                    nmsg.obj = msg.obj;
1330                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1331                    return;
1332                }
1333                ProcessRecord app = (ProcessRecord)msg.obj;
1334                synchronized (ActivityManagerService.this) {
1335                    processStartTimedOutLocked(app);
1336                }
1337            } break;
1338            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1339                synchronized (ActivityManagerService.this) {
1340                    doPendingActivityLaunchesLocked(true);
1341                }
1342            } break;
1343            case KILL_APPLICATION_MSG: {
1344                synchronized (ActivityManagerService.this) {
1345                    int appid = msg.arg1;
1346                    boolean restart = (msg.arg2 == 1);
1347                    Bundle bundle = (Bundle)msg.obj;
1348                    String pkg = bundle.getString("pkg");
1349                    String reason = bundle.getString("reason");
1350                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1351                            false, UserHandle.USER_ALL, reason);
1352                }
1353            } break;
1354            case FINALIZE_PENDING_INTENT_MSG: {
1355                ((PendingIntentRecord)msg.obj).completeFinalize();
1356            } break;
1357            case POST_HEAVY_NOTIFICATION_MSG: {
1358                INotificationManager inm = NotificationManager.getService();
1359                if (inm == null) {
1360                    return;
1361                }
1362
1363                ActivityRecord root = (ActivityRecord)msg.obj;
1364                ProcessRecord process = root.app;
1365                if (process == null) {
1366                    return;
1367                }
1368
1369                try {
1370                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1371                    String text = mContext.getString(R.string.heavy_weight_notification,
1372                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1373                    Notification notification = new Notification();
1374                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1375                    notification.when = 0;
1376                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1377                    notification.tickerText = text;
1378                    notification.defaults = 0; // please be quiet
1379                    notification.sound = null;
1380                    notification.vibrate = null;
1381                    notification.setLatestEventInfo(context, text,
1382                            mContext.getText(R.string.heavy_weight_notification_detail),
1383                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1384                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1385                                    new UserHandle(root.userId)));
1386
1387                    try {
1388                        int[] outId = new int[1];
1389                        inm.enqueueNotificationWithTag("android", "android", null,
1390                                R.string.heavy_weight_notification,
1391                                notification, outId, root.userId);
1392                    } catch (RuntimeException e) {
1393                        Slog.w(ActivityManagerService.TAG,
1394                                "Error showing notification for heavy-weight app", e);
1395                    } catch (RemoteException e) {
1396                    }
1397                } catch (NameNotFoundException e) {
1398                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1399                }
1400            } break;
1401            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1402                INotificationManager inm = NotificationManager.getService();
1403                if (inm == null) {
1404                    return;
1405                }
1406                try {
1407                    inm.cancelNotificationWithTag("android", null,
1408                            R.string.heavy_weight_notification,  msg.arg1);
1409                } catch (RuntimeException e) {
1410                    Slog.w(ActivityManagerService.TAG,
1411                            "Error canceling notification for service", e);
1412                } catch (RemoteException e) {
1413                }
1414            } break;
1415            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1416                synchronized (ActivityManagerService.this) {
1417                    checkExcessivePowerUsageLocked(true);
1418                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1419                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1420                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1421                }
1422            } break;
1423            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1424                synchronized (ActivityManagerService.this) {
1425                    ActivityRecord ar = (ActivityRecord)msg.obj;
1426                    if (mCompatModeDialog != null) {
1427                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1428                                ar.info.applicationInfo.packageName)) {
1429                            return;
1430                        }
1431                        mCompatModeDialog.dismiss();
1432                        mCompatModeDialog = null;
1433                    }
1434                    if (ar != null && false) {
1435                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1436                                ar.packageName)) {
1437                            int mode = mCompatModePackages.computeCompatModeLocked(
1438                                    ar.info.applicationInfo);
1439                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1440                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1441                                mCompatModeDialog = new CompatModeDialog(
1442                                        ActivityManagerService.this, mContext,
1443                                        ar.info.applicationInfo);
1444                                mCompatModeDialog.show();
1445                            }
1446                        }
1447                    }
1448                }
1449                break;
1450            }
1451            case DISPATCH_PROCESSES_CHANGED: {
1452                dispatchProcessesChanged();
1453                break;
1454            }
1455            case DISPATCH_PROCESS_DIED: {
1456                final int pid = msg.arg1;
1457                final int uid = msg.arg2;
1458                dispatchProcessDied(pid, uid);
1459                break;
1460            }
1461            case REPORT_MEM_USAGE_MSG: {
1462                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1463                Thread thread = new Thread() {
1464                    @Override public void run() {
1465                        final SparseArray<ProcessMemInfo> infoMap
1466                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1467                        for (int i=0, N=memInfos.size(); i<N; i++) {
1468                            ProcessMemInfo mi = memInfos.get(i);
1469                            infoMap.put(mi.pid, mi);
1470                        }
1471                        updateCpuStatsNow();
1472                        synchronized (mProcessCpuThread) {
1473                            final int N = mProcessCpuTracker.countStats();
1474                            for (int i=0; i<N; i++) {
1475                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1476                                if (st.vsize > 0) {
1477                                    long pss = Debug.getPss(st.pid, null);
1478                                    if (pss > 0) {
1479                                        if (infoMap.indexOfKey(st.pid) < 0) {
1480                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1481                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1482                                            mi.pss = pss;
1483                                            memInfos.add(mi);
1484                                        }
1485                                    }
1486                                }
1487                            }
1488                        }
1489
1490                        long totalPss = 0;
1491                        for (int i=0, N=memInfos.size(); i<N; i++) {
1492                            ProcessMemInfo mi = memInfos.get(i);
1493                            if (mi.pss == 0) {
1494                                mi.pss = Debug.getPss(mi.pid, null);
1495                            }
1496                            totalPss += mi.pss;
1497                        }
1498                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1499                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1500                                if (lhs.oomAdj != rhs.oomAdj) {
1501                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1502                                }
1503                                if (lhs.pss != rhs.pss) {
1504                                    return lhs.pss < rhs.pss ? 1 : -1;
1505                                }
1506                                return 0;
1507                            }
1508                        });
1509
1510                        StringBuilder tag = new StringBuilder(128);
1511                        StringBuilder stack = new StringBuilder(128);
1512                        tag.append("Low on memory -- ");
1513                        appendMemBucket(tag, totalPss, "total", false);
1514                        appendMemBucket(stack, totalPss, "total", true);
1515
1516                        StringBuilder logBuilder = new StringBuilder(1024);
1517                        logBuilder.append("Low on memory:\n");
1518
1519                        boolean firstLine = true;
1520                        int lastOomAdj = Integer.MIN_VALUE;
1521                        for (int i=0, N=memInfos.size(); i<N; i++) {
1522                            ProcessMemInfo mi = memInfos.get(i);
1523
1524                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1525                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1526                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1527                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1528                                if (lastOomAdj != mi.oomAdj) {
1529                                    lastOomAdj = mi.oomAdj;
1530                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1531                                        tag.append(" / ");
1532                                    }
1533                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1534                                        if (firstLine) {
1535                                            stack.append(":");
1536                                            firstLine = false;
1537                                        }
1538                                        stack.append("\n\t at ");
1539                                    } else {
1540                                        stack.append("$");
1541                                    }
1542                                } else {
1543                                    tag.append(" ");
1544                                    stack.append("$");
1545                                }
1546                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1547                                    appendMemBucket(tag, mi.pss, mi.name, false);
1548                                }
1549                                appendMemBucket(stack, mi.pss, mi.name, true);
1550                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1551                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1552                                    stack.append("(");
1553                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1554                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1555                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1556                                            stack.append(":");
1557                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1558                                        }
1559                                    }
1560                                    stack.append(")");
1561                                }
1562                            }
1563
1564                            logBuilder.append("  ");
1565                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1566                            logBuilder.append(' ');
1567                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1568                            logBuilder.append(' ');
1569                            ProcessList.appendRamKb(logBuilder, mi.pss);
1570                            logBuilder.append(" kB: ");
1571                            logBuilder.append(mi.name);
1572                            logBuilder.append(" (");
1573                            logBuilder.append(mi.pid);
1574                            logBuilder.append(") ");
1575                            logBuilder.append(mi.adjType);
1576                            logBuilder.append('\n');
1577                            if (mi.adjReason != null) {
1578                                logBuilder.append("                      ");
1579                                logBuilder.append(mi.adjReason);
1580                                logBuilder.append('\n');
1581                            }
1582                        }
1583
1584                        logBuilder.append("           ");
1585                        ProcessList.appendRamKb(logBuilder, totalPss);
1586                        logBuilder.append(" kB: TOTAL\n");
1587
1588                        long[] infos = new long[Debug.MEMINFO_COUNT];
1589                        Debug.getMemInfo(infos);
1590                        logBuilder.append("  MemInfo: ");
1591                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1592                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1593                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1594                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1595                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1596                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1597                            logBuilder.append("  ZRAM: ");
1598                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1599                            logBuilder.append(" kB RAM, ");
1600                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1601                            logBuilder.append(" kB swap total, ");
1602                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1603                            logBuilder.append(" kB swap free\n");
1604                        }
1605                        Slog.i(TAG, logBuilder.toString());
1606
1607                        StringBuilder dropBuilder = new StringBuilder(1024);
1608                        /*
1609                        StringWriter oomSw = new StringWriter();
1610                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1611                        StringWriter catSw = new StringWriter();
1612                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1613                        String[] emptyArgs = new String[] { };
1614                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1615                        oomPw.flush();
1616                        String oomString = oomSw.toString();
1617                        */
1618                        dropBuilder.append(stack);
1619                        dropBuilder.append('\n');
1620                        dropBuilder.append('\n');
1621                        dropBuilder.append(logBuilder);
1622                        dropBuilder.append('\n');
1623                        /*
1624                        dropBuilder.append(oomString);
1625                        dropBuilder.append('\n');
1626                        */
1627                        StringWriter catSw = new StringWriter();
1628                        synchronized (ActivityManagerService.this) {
1629                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1630                            String[] emptyArgs = new String[] { };
1631                            catPw.println();
1632                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1633                            catPw.println();
1634                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1635                                    false, false, null);
1636                            catPw.println();
1637                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1638                            catPw.flush();
1639                        }
1640                        dropBuilder.append(catSw.toString());
1641                        addErrorToDropBox("lowmem", null, "system_server", null,
1642                                null, tag.toString(), dropBuilder.toString(), null, null);
1643                        //Slog.i(TAG, "Sent to dropbox:");
1644                        //Slog.i(TAG, dropBuilder.toString());
1645                        synchronized (ActivityManagerService.this) {
1646                            long now = SystemClock.uptimeMillis();
1647                            if (mLastMemUsageReportTime < now) {
1648                                mLastMemUsageReportTime = now;
1649                            }
1650                        }
1651                    }
1652                };
1653                thread.start();
1654                break;
1655            }
1656            case REPORT_USER_SWITCH_MSG: {
1657                dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1658                break;
1659            }
1660            case CONTINUE_USER_SWITCH_MSG: {
1661                continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1662                break;
1663            }
1664            case USER_SWITCH_TIMEOUT_MSG: {
1665                timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1666                break;
1667            }
1668            case IMMERSIVE_MODE_LOCK_MSG: {
1669                final boolean nextState = (msg.arg1 != 0);
1670                if (mUpdateLock.isHeld() != nextState) {
1671                    if (DEBUG_IMMERSIVE) {
1672                        final ActivityRecord r = (ActivityRecord) msg.obj;
1673                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1674                    }
1675                    if (nextState) {
1676                        mUpdateLock.acquire();
1677                    } else {
1678                        mUpdateLock.release();
1679                    }
1680                }
1681                break;
1682            }
1683            case PERSIST_URI_GRANTS_MSG: {
1684                writeGrantedUriPermissions();
1685                break;
1686            }
1687            case REQUEST_ALL_PSS_MSG: {
1688                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1689                break;
1690            }
1691            case START_RELATED_USERS_MSG: {
1692                synchronized (ActivityManagerService.this) {
1693                    startRelatedUsersLocked();
1694                }
1695                break;
1696            }
1697            case UPDATE_TIME: {
1698                synchronized (ActivityManagerService.this) {
1699                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1700                        ProcessRecord r = mLruProcesses.get(i);
1701                        if (r.thread != null) {
1702                            try {
1703                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1704                            } catch (RemoteException ex) {
1705                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1706                            }
1707                        }
1708                    }
1709                }
1710                break;
1711            }
1712            }
1713        }
1714    };
1715
1716    static final int COLLECT_PSS_BG_MSG = 1;
1717
1718    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1719        @Override
1720        public void handleMessage(Message msg) {
1721            switch (msg.what) {
1722            case COLLECT_PSS_BG_MSG: {
1723                int i=0, num=0;
1724                long start = SystemClock.uptimeMillis();
1725                long[] tmp = new long[1];
1726                do {
1727                    ProcessRecord proc;
1728                    int procState;
1729                    int pid;
1730                    synchronized (ActivityManagerService.this) {
1731                        if (i >= mPendingPssProcesses.size()) {
1732                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1733                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1734                            mPendingPssProcesses.clear();
1735                            return;
1736                        }
1737                        proc = mPendingPssProcesses.get(i);
1738                        procState = proc.pssProcState;
1739                        if (proc.thread != null && procState == proc.setProcState) {
1740                            pid = proc.pid;
1741                        } else {
1742                            proc = null;
1743                            pid = 0;
1744                        }
1745                        i++;
1746                    }
1747                    if (proc != null) {
1748                        long pss = Debug.getPss(pid, tmp);
1749                        synchronized (ActivityManagerService.this) {
1750                            if (proc.thread != null && proc.setProcState == procState
1751                                    && proc.pid == pid) {
1752                                num++;
1753                                proc.lastPssTime = SystemClock.uptimeMillis();
1754                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1755                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1756                                        + ": " + pss + " lastPss=" + proc.lastPss
1757                                        + " state=" + ProcessList.makeProcStateString(procState));
1758                                if (proc.initialIdlePss == 0) {
1759                                    proc.initialIdlePss = pss;
1760                                }
1761                                proc.lastPss = pss;
1762                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1763                                    proc.lastCachedPss = pss;
1764                                }
1765                            }
1766                        }
1767                    }
1768                } while (true);
1769            }
1770            }
1771        }
1772    };
1773
1774    public void setSystemProcess() {
1775        try {
1776            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1777            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1778            ServiceManager.addService("meminfo", new MemBinder(this));
1779            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1780            ServiceManager.addService("dbinfo", new DbBinder(this));
1781            if (MONITOR_CPU_USAGE) {
1782                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1783            }
1784            ServiceManager.addService("permission", new PermissionController(this));
1785
1786            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1787                    "android", STOCK_PM_FLAGS);
1788            mSystemThread.installSystemApplicationInfo(info);
1789
1790            synchronized (this) {
1791                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
1792                app.persistent = true;
1793                app.pid = MY_PID;
1794                app.maxAdj = ProcessList.SYSTEM_ADJ;
1795                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1796                mProcessNames.put(app.processName, app.uid, app);
1797                synchronized (mPidsSelfLocked) {
1798                    mPidsSelfLocked.put(app.pid, app);
1799                }
1800                updateLruProcessLocked(app, false, null);
1801                updateOomAdjLocked();
1802            }
1803        } catch (PackageManager.NameNotFoundException e) {
1804            throw new RuntimeException(
1805                    "Unable to find android system package", e);
1806        }
1807    }
1808
1809    public void setWindowManager(WindowManagerService wm) {
1810        mWindowManager = wm;
1811        mStackSupervisor.setWindowManager(wm);
1812    }
1813
1814    public void startObservingNativeCrashes() {
1815        final NativeCrashListener ncl = new NativeCrashListener(this);
1816        ncl.start();
1817    }
1818
1819    public IAppOpsService getAppOpsService() {
1820        return mAppOpsService;
1821    }
1822
1823    static class MemBinder extends Binder {
1824        ActivityManagerService mActivityManagerService;
1825        MemBinder(ActivityManagerService activityManagerService) {
1826            mActivityManagerService = activityManagerService;
1827        }
1828
1829        @Override
1830        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1831            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1832                    != PackageManager.PERMISSION_GRANTED) {
1833                pw.println("Permission Denial: can't dump meminfo from from pid="
1834                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1835                        + " without permission " + android.Manifest.permission.DUMP);
1836                return;
1837            }
1838
1839            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1840        }
1841    }
1842
1843    static class GraphicsBinder extends Binder {
1844        ActivityManagerService mActivityManagerService;
1845        GraphicsBinder(ActivityManagerService activityManagerService) {
1846            mActivityManagerService = activityManagerService;
1847        }
1848
1849        @Override
1850        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1851            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1852                    != PackageManager.PERMISSION_GRANTED) {
1853                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1854                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1855                        + " without permission " + android.Manifest.permission.DUMP);
1856                return;
1857            }
1858
1859            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1860        }
1861    }
1862
1863    static class DbBinder extends Binder {
1864        ActivityManagerService mActivityManagerService;
1865        DbBinder(ActivityManagerService activityManagerService) {
1866            mActivityManagerService = activityManagerService;
1867        }
1868
1869        @Override
1870        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1871            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1872                    != PackageManager.PERMISSION_GRANTED) {
1873                pw.println("Permission Denial: can't dump dbinfo from from pid="
1874                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1875                        + " without permission " + android.Manifest.permission.DUMP);
1876                return;
1877            }
1878
1879            mActivityManagerService.dumpDbInfo(fd, pw, args);
1880        }
1881    }
1882
1883    static class CpuBinder extends Binder {
1884        ActivityManagerService mActivityManagerService;
1885        CpuBinder(ActivityManagerService activityManagerService) {
1886            mActivityManagerService = activityManagerService;
1887        }
1888
1889        @Override
1890        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1891            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1892                    != PackageManager.PERMISSION_GRANTED) {
1893                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1894                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1895                        + " without permission " + android.Manifest.permission.DUMP);
1896                return;
1897            }
1898
1899            synchronized (mActivityManagerService.mProcessCpuThread) {
1900                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1901                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1902                        SystemClock.uptimeMillis()));
1903            }
1904        }
1905    }
1906
1907    public static final class Lifecycle extends SystemService {
1908        private final ActivityManagerService mService;
1909
1910        public Lifecycle(Context context) {
1911            super(context);
1912            mService = new ActivityManagerService(context);
1913        }
1914
1915        @Override
1916        public void onStart() {
1917            mService.start();
1918        }
1919
1920        public ActivityManagerService getService() {
1921            return mService;
1922        }
1923    }
1924
1925    // Note: This method is invoked on the main thread but may need to attach various
1926    // handlers to other threads.  So take care to be explicit about the looper.
1927    public ActivityManagerService(Context systemContext) {
1928        mContext = systemContext;
1929        mFactoryTest = FactoryTest.getMode();
1930        mSystemThread = ActivityThread.currentActivityThread();
1931
1932        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1933
1934        mHandlerThread = new ServiceThread(TAG,
1935                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
1936        mHandlerThread.start();
1937        mHandler = new MainHandler(mHandlerThread.getLooper());
1938
1939        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
1940                "foreground", BROADCAST_FG_TIMEOUT, false);
1941        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
1942                "background", BROADCAST_BG_TIMEOUT, true);
1943        mBroadcastQueues[0] = mFgBroadcastQueue;
1944        mBroadcastQueues[1] = mBgBroadcastQueue;
1945
1946        mServices = new ActiveServices(this);
1947        mProviderMap = new ProviderMap(this);
1948
1949        // TODO: Move creation of battery stats service outside of activity manager service.
1950        File dataDir = Environment.getDataDirectory();
1951        File systemDir = new File(dataDir, "system");
1952        systemDir.mkdirs();
1953        mBatteryStatsService = new BatteryStatsService(new File(
1954                systemDir, "batterystats.bin").toString(), mHandler);
1955        mBatteryStatsService.getActiveStatistics().readLocked();
1956        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1957        mOnBattery = DEBUG_POWER ? true
1958                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1959        mBatteryStatsService.getActiveStatistics().setCallback(this);
1960
1961        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
1962
1963        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
1964        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
1965
1966        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
1967
1968        // User 0 is the first and only user that runs at boot.
1969        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1970        mUserLru.add(Integer.valueOf(0));
1971        updateStartedUserArrayLocked();
1972
1973        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1974            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1975
1976        mConfiguration.setToDefaults();
1977        mConfiguration.setLocale(Locale.getDefault());
1978
1979        mConfigurationSeq = mConfiguration.seq = 1;
1980        mProcessCpuTracker.init();
1981
1982        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
1983        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
1984        mStackSupervisor = new ActivityStackSupervisor(this);
1985
1986        mProcessCpuThread = new Thread("CpuTracker") {
1987            @Override
1988            public void run() {
1989                while (true) {
1990                    try {
1991                        try {
1992                            synchronized(this) {
1993                                final long now = SystemClock.uptimeMillis();
1994                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1995                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1996                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1997                                //        + ", write delay=" + nextWriteDelay);
1998                                if (nextWriteDelay < nextCpuDelay) {
1999                                    nextCpuDelay = nextWriteDelay;
2000                                }
2001                                if (nextCpuDelay > 0) {
2002                                    mProcessCpuMutexFree.set(true);
2003                                    this.wait(nextCpuDelay);
2004                                }
2005                            }
2006                        } catch (InterruptedException e) {
2007                        }
2008                        updateCpuStatsNow();
2009                    } catch (Exception e) {
2010                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2011                    }
2012                }
2013            }
2014        };
2015
2016        Watchdog.getInstance().addMonitor(this);
2017        Watchdog.getInstance().addThread(mHandler);
2018    }
2019
2020    private void start() {
2021        mProcessCpuThread.start();
2022
2023        mBatteryStatsService.publish(mContext);
2024        mUsageStatsService.publish(mContext);
2025        mAppOpsService.publish(mContext);
2026        startRunning(null, null, null, null);
2027    }
2028
2029    @Override
2030    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2031            throws RemoteException {
2032        if (code == SYSPROPS_TRANSACTION) {
2033            // We need to tell all apps about the system property change.
2034            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2035            synchronized(this) {
2036                final int NP = mProcessNames.getMap().size();
2037                for (int ip=0; ip<NP; ip++) {
2038                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2039                    final int NA = apps.size();
2040                    for (int ia=0; ia<NA; ia++) {
2041                        ProcessRecord app = apps.valueAt(ia);
2042                        if (app.thread != null) {
2043                            procs.add(app.thread.asBinder());
2044                        }
2045                    }
2046                }
2047            }
2048
2049            int N = procs.size();
2050            for (int i=0; i<N; i++) {
2051                Parcel data2 = Parcel.obtain();
2052                try {
2053                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2054                } catch (RemoteException e) {
2055                }
2056                data2.recycle();
2057            }
2058        }
2059        try {
2060            return super.onTransact(code, data, reply, flags);
2061        } catch (RuntimeException e) {
2062            // The activity manager only throws security exceptions, so let's
2063            // log all others.
2064            if (!(e instanceof SecurityException)) {
2065                Slog.wtf(TAG, "Activity Manager Crash", e);
2066            }
2067            throw e;
2068        }
2069    }
2070
2071    void updateCpuStats() {
2072        final long now = SystemClock.uptimeMillis();
2073        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2074            return;
2075        }
2076        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2077            synchronized (mProcessCpuThread) {
2078                mProcessCpuThread.notify();
2079            }
2080        }
2081    }
2082
2083    void updateCpuStatsNow() {
2084        synchronized (mProcessCpuThread) {
2085            mProcessCpuMutexFree.set(false);
2086            final long now = SystemClock.uptimeMillis();
2087            boolean haveNewCpuStats = false;
2088
2089            if (MONITOR_CPU_USAGE &&
2090                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2091                mLastCpuTime.set(now);
2092                haveNewCpuStats = true;
2093                mProcessCpuTracker.update();
2094                //Slog.i(TAG, mProcessCpu.printCurrentState());
2095                //Slog.i(TAG, "Total CPU usage: "
2096                //        + mProcessCpu.getTotalCpuPercent() + "%");
2097
2098                // Slog the cpu usage if the property is set.
2099                if ("true".equals(SystemProperties.get("events.cpu"))) {
2100                    int user = mProcessCpuTracker.getLastUserTime();
2101                    int system = mProcessCpuTracker.getLastSystemTime();
2102                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2103                    int irq = mProcessCpuTracker.getLastIrqTime();
2104                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2105                    int idle = mProcessCpuTracker.getLastIdleTime();
2106
2107                    int total = user + system + iowait + irq + softIrq + idle;
2108                    if (total == 0) total = 1;
2109
2110                    EventLog.writeEvent(EventLogTags.CPU,
2111                            ((user+system+iowait+irq+softIrq) * 100) / total,
2112                            (user * 100) / total,
2113                            (system * 100) / total,
2114                            (iowait * 100) / total,
2115                            (irq * 100) / total,
2116                            (softIrq * 100) / total);
2117                }
2118            }
2119
2120            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2121            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2122            synchronized(bstats) {
2123                synchronized(mPidsSelfLocked) {
2124                    if (haveNewCpuStats) {
2125                        if (mOnBattery) {
2126                            int perc = bstats.startAddingCpuLocked();
2127                            int totalUTime = 0;
2128                            int totalSTime = 0;
2129                            final int N = mProcessCpuTracker.countStats();
2130                            for (int i=0; i<N; i++) {
2131                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2132                                if (!st.working) {
2133                                    continue;
2134                                }
2135                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2136                                int otherUTime = (st.rel_utime*perc)/100;
2137                                int otherSTime = (st.rel_stime*perc)/100;
2138                                totalUTime += otherUTime;
2139                                totalSTime += otherSTime;
2140                                if (pr != null) {
2141                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2142                                    if (ps == null || !ps.isActive()) {
2143                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2144                                                pr.info.uid, pr.processName);
2145                                    }
2146                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2147                                            st.rel_stime-otherSTime);
2148                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2149                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2150                                } else {
2151                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2152                                    if (ps == null || !ps.isActive()) {
2153                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2154                                                bstats.mapUid(st.uid), st.name);
2155                                    }
2156                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2157                                            st.rel_stime-otherSTime);
2158                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2159                                }
2160                            }
2161                            bstats.finishAddingCpuLocked(perc, totalUTime,
2162                                    totalSTime, cpuSpeedTimes);
2163                        }
2164                    }
2165                }
2166
2167                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2168                    mLastWriteTime = now;
2169                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2170                }
2171            }
2172        }
2173    }
2174
2175    @Override
2176    public void batteryNeedsCpuUpdate() {
2177        updateCpuStatsNow();
2178    }
2179
2180    @Override
2181    public void batteryPowerChanged(boolean onBattery) {
2182        // When plugging in, update the CPU stats first before changing
2183        // the plug state.
2184        updateCpuStatsNow();
2185        synchronized (this) {
2186            synchronized(mPidsSelfLocked) {
2187                mOnBattery = DEBUG_POWER ? true : onBattery;
2188            }
2189        }
2190    }
2191
2192    /**
2193     * Initialize the application bind args. These are passed to each
2194     * process when the bindApplication() IPC is sent to the process. They're
2195     * lazily setup to make sure the services are running when they're asked for.
2196     */
2197    private HashMap<String, IBinder> getCommonServicesLocked() {
2198        if (mAppBindArgs == null) {
2199            mAppBindArgs = new HashMap<String, IBinder>();
2200
2201            // Setup the application init args
2202            mAppBindArgs.put("package", ServiceManager.getService("package"));
2203            mAppBindArgs.put("window", ServiceManager.getService("window"));
2204            mAppBindArgs.put(Context.ALARM_SERVICE,
2205                    ServiceManager.getService(Context.ALARM_SERVICE));
2206        }
2207        return mAppBindArgs;
2208    }
2209
2210    final void setFocusedActivityLocked(ActivityRecord r) {
2211        if (mFocusedActivity != r) {
2212            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2213            mFocusedActivity = r;
2214            mStackSupervisor.setFocusedStack(r);
2215            if (r != null) {
2216                mWindowManager.setFocusedApp(r.appToken, true);
2217            }
2218            applyUpdateLockStateLocked(r);
2219        }
2220    }
2221
2222    @Override
2223    public void setFocusedStack(int stackId) {
2224        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2225        synchronized (ActivityManagerService.this) {
2226            ActivityStack stack = mStackSupervisor.getStack(stackId);
2227            if (stack != null) {
2228                ActivityRecord r = stack.topRunningActivityLocked(null);
2229                if (r != null) {
2230                    setFocusedActivityLocked(r);
2231                }
2232            }
2233        }
2234    }
2235
2236    @Override
2237    public void notifyActivityDrawn(IBinder token) {
2238        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2239        synchronized (this) {
2240            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2241            if (r != null) {
2242                r.task.stack.notifyActivityDrawnLocked(r);
2243            }
2244        }
2245    }
2246
2247    final void applyUpdateLockStateLocked(ActivityRecord r) {
2248        // Modifications to the UpdateLock state are done on our handler, outside
2249        // the activity manager's locks.  The new state is determined based on the
2250        // state *now* of the relevant activity record.  The object is passed to
2251        // the handler solely for logging detail, not to be consulted/modified.
2252        final boolean nextState = r != null && r.immersive;
2253        mHandler.sendMessage(
2254                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2255    }
2256
2257    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2258        Message msg = Message.obtain();
2259        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2260        msg.obj = r.task.askedCompatMode ? null : r;
2261        mHandler.sendMessage(msg);
2262    }
2263
2264    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2265            String what, Object obj, ProcessRecord srcApp) {
2266        app.lastActivityTime = now;
2267
2268        if (app.activities.size() > 0) {
2269            // Don't want to touch dependent processes that are hosting activities.
2270            return index;
2271        }
2272
2273        int lrui = mLruProcesses.lastIndexOf(app);
2274        if (lrui < 0) {
2275            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2276                    + what + " " + obj + " from " + srcApp);
2277            return index;
2278        }
2279
2280        if (lrui >= index) {
2281            // Don't want to cause this to move dependent processes *back* in the
2282            // list as if they were less frequently used.
2283            return index;
2284        }
2285
2286        if (lrui >= mLruProcessActivityStart) {
2287            // Don't want to touch dependent processes that are hosting activities.
2288            return index;
2289        }
2290
2291        mLruProcesses.remove(lrui);
2292        if (index > 0) {
2293            index--;
2294        }
2295        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2296                + " in LRU list: " + app);
2297        mLruProcesses.add(index, app);
2298        return index;
2299    }
2300
2301    final void removeLruProcessLocked(ProcessRecord app) {
2302        int lrui = mLruProcesses.lastIndexOf(app);
2303        if (lrui >= 0) {
2304            if (lrui <= mLruProcessActivityStart) {
2305                mLruProcessActivityStart--;
2306            }
2307            if (lrui <= mLruProcessServiceStart) {
2308                mLruProcessServiceStart--;
2309            }
2310            mLruProcesses.remove(lrui);
2311        }
2312    }
2313
2314    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2315            ProcessRecord client) {
2316        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
2317        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2318        if (!activityChange && hasActivity) {
2319            // The process has activties, so we are only going to allow activity-based
2320            // adjustments move it.  It should be kept in the front of the list with other
2321            // processes that have activities, and we don't want those to change their
2322            // order except due to activity operations.
2323            return;
2324        }
2325
2326        mLruSeq++;
2327        final long now = SystemClock.uptimeMillis();
2328        app.lastActivityTime = now;
2329
2330        // First a quick reject: if the app is already at the position we will
2331        // put it, then there is nothing to do.
2332        if (hasActivity) {
2333            final int N = mLruProcesses.size();
2334            if (N > 0 && mLruProcesses.get(N-1) == app) {
2335                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2336                return;
2337            }
2338        } else {
2339            if (mLruProcessServiceStart > 0
2340                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2341                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2342                return;
2343            }
2344        }
2345
2346        int lrui = mLruProcesses.lastIndexOf(app);
2347
2348        if (app.persistent && lrui >= 0) {
2349            // We don't care about the position of persistent processes, as long as
2350            // they are in the list.
2351            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2352            return;
2353        }
2354
2355        /* In progress: compute new position first, so we can avoid doing work
2356           if the process is not actually going to move.  Not yet working.
2357        int addIndex;
2358        int nextIndex;
2359        boolean inActivity = false, inService = false;
2360        if (hasActivity) {
2361            // Process has activities, put it at the very tipsy-top.
2362            addIndex = mLruProcesses.size();
2363            nextIndex = mLruProcessServiceStart;
2364            inActivity = true;
2365        } else if (hasService) {
2366            // Process has services, put it at the top of the service list.
2367            addIndex = mLruProcessActivityStart;
2368            nextIndex = mLruProcessServiceStart;
2369            inActivity = true;
2370            inService = true;
2371        } else  {
2372            // Process not otherwise of interest, it goes to the top of the non-service area.
2373            addIndex = mLruProcessServiceStart;
2374            if (client != null) {
2375                int clientIndex = mLruProcesses.lastIndexOf(client);
2376                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2377                        + app);
2378                if (clientIndex >= 0 && addIndex > clientIndex) {
2379                    addIndex = clientIndex;
2380                }
2381            }
2382            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2383        }
2384
2385        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2386                + mLruProcessActivityStart + "): " + app);
2387        */
2388
2389        if (lrui >= 0) {
2390            if (lrui < mLruProcessActivityStart) {
2391                mLruProcessActivityStart--;
2392            }
2393            if (lrui < mLruProcessServiceStart) {
2394                mLruProcessServiceStart--;
2395            }
2396            /*
2397            if (addIndex > lrui) {
2398                addIndex--;
2399            }
2400            if (nextIndex > lrui) {
2401                nextIndex--;
2402            }
2403            */
2404            mLruProcesses.remove(lrui);
2405        }
2406
2407        /*
2408        mLruProcesses.add(addIndex, app);
2409        if (inActivity) {
2410            mLruProcessActivityStart++;
2411        }
2412        if (inService) {
2413            mLruProcessActivityStart++;
2414        }
2415        */
2416
2417        int nextIndex;
2418        if (hasActivity) {
2419            final int N = mLruProcesses.size();
2420            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2421                // Process doesn't have activities, but has clients with
2422                // activities...  move it up, but one below the top (the top
2423                // should always have a real activity).
2424                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2425                mLruProcesses.add(N-1, app);
2426                // To keep it from spamming the LRU list (by making a bunch of clients),
2427                // we will push down any other entries owned by the app.
2428                final int uid = app.info.uid;
2429                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2430                    ProcessRecord subProc = mLruProcesses.get(i);
2431                    if (subProc.info.uid == uid) {
2432                        // We want to push this one down the list.  If the process after
2433                        // it is for the same uid, however, don't do so, because we don't
2434                        // want them internally to be re-ordered.
2435                        if (mLruProcesses.get(i-1).info.uid != uid) {
2436                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2437                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2438                            ProcessRecord tmp = mLruProcesses.get(i);
2439                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2440                            mLruProcesses.set(i-1, tmp);
2441                            i--;
2442                        }
2443                    } else {
2444                        // A gap, we can stop here.
2445                        break;
2446                    }
2447                }
2448            } else {
2449                // Process has activities, put it at the very tipsy-top.
2450                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2451                mLruProcesses.add(app);
2452            }
2453            nextIndex = mLruProcessServiceStart;
2454        } else if (hasService) {
2455            // Process has services, put it at the top of the service list.
2456            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2457            mLruProcesses.add(mLruProcessActivityStart, app);
2458            nextIndex = mLruProcessServiceStart;
2459            mLruProcessActivityStart++;
2460        } else  {
2461            // Process not otherwise of interest, it goes to the top of the non-service area.
2462            int index = mLruProcessServiceStart;
2463            if (client != null) {
2464                // If there is a client, don't allow the process to be moved up higher
2465                // in the list than that client.
2466                int clientIndex = mLruProcesses.lastIndexOf(client);
2467                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2468                        + " when updating " + app);
2469                if (clientIndex <= lrui) {
2470                    // Don't allow the client index restriction to push it down farther in the
2471                    // list than it already is.
2472                    clientIndex = lrui;
2473                }
2474                if (clientIndex >= 0 && index > clientIndex) {
2475                    index = clientIndex;
2476                }
2477            }
2478            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2479            mLruProcesses.add(index, app);
2480            nextIndex = index-1;
2481            mLruProcessActivityStart++;
2482            mLruProcessServiceStart++;
2483        }
2484
2485        // If the app is currently using a content provider or service,
2486        // bump those processes as well.
2487        for (int j=app.connections.size()-1; j>=0; j--) {
2488            ConnectionRecord cr = app.connections.valueAt(j);
2489            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2490                    && cr.binding.service.app != null
2491                    && cr.binding.service.app.lruSeq != mLruSeq
2492                    && !cr.binding.service.app.persistent) {
2493                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2494                        "service connection", cr, app);
2495            }
2496        }
2497        for (int j=app.conProviders.size()-1; j>=0; j--) {
2498            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2499            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2500                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2501                        "provider reference", cpr, app);
2502            }
2503        }
2504    }
2505
2506    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2507        if (uid == Process.SYSTEM_UID) {
2508            // The system gets to run in any process.  If there are multiple
2509            // processes with the same uid, just pick the first (this
2510            // should never happen).
2511            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2512            if (procs == null) return null;
2513            final int N = procs.size();
2514            for (int i = 0; i < N; i++) {
2515                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2516            }
2517        }
2518        ProcessRecord proc = mProcessNames.get(processName, uid);
2519        if (false && proc != null && !keepIfLarge
2520                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2521                && proc.lastCachedPss >= 4000) {
2522            // Turn this condition on to cause killing to happen regularly, for testing.
2523            if (proc.baseProcessTracker != null) {
2524                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2525            }
2526            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2527                    + "k from cached");
2528        } else if (proc != null && !keepIfLarge
2529                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2530                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2531            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2532            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2533                if (proc.baseProcessTracker != null) {
2534                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2535                }
2536                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2537                        + "k from cached");
2538            }
2539        }
2540        return proc;
2541    }
2542
2543    void ensurePackageDexOpt(String packageName) {
2544        IPackageManager pm = AppGlobals.getPackageManager();
2545        try {
2546            if (pm.performDexOpt(packageName)) {
2547                mDidDexOpt = true;
2548            }
2549        } catch (RemoteException e) {
2550        }
2551    }
2552
2553    boolean isNextTransitionForward() {
2554        int transit = mWindowManager.getPendingAppTransition();
2555        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2556                || transit == AppTransition.TRANSIT_TASK_OPEN
2557                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2558    }
2559
2560    final ProcessRecord startProcessLocked(String processName,
2561            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2562            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2563            boolean isolated, boolean keepIfLarge) {
2564        ProcessRecord app;
2565        if (!isolated) {
2566            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2567        } else {
2568            // If this is an isolated process, it can't re-use an existing process.
2569            app = null;
2570        }
2571        // We don't have to do anything more if:
2572        // (1) There is an existing application record; and
2573        // (2) The caller doesn't think it is dead, OR there is no thread
2574        //     object attached to it so we know it couldn't have crashed; and
2575        // (3) There is a pid assigned to it, so it is either starting or
2576        //     already running.
2577        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2578                + " app=" + app + " knownToBeDead=" + knownToBeDead
2579                + " thread=" + (app != null ? app.thread : null)
2580                + " pid=" + (app != null ? app.pid : -1));
2581        if (app != null && app.pid > 0) {
2582            if (!knownToBeDead || app.thread == null) {
2583                // We already have the app running, or are waiting for it to
2584                // come up (we have a pid but not yet its thread), so keep it.
2585                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2586                // If this is a new package in the process, add the package to the list
2587                app.addPackage(info.packageName, mProcessStats);
2588                return app;
2589            }
2590
2591            // An application record is attached to a previous process,
2592            // clean it up now.
2593            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2594            handleAppDiedLocked(app, true, true);
2595        }
2596
2597        String hostingNameStr = hostingName != null
2598                ? hostingName.flattenToShortString() : null;
2599
2600        if (!isolated) {
2601            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2602                // If we are in the background, then check to see if this process
2603                // is bad.  If so, we will just silently fail.
2604                if (mBadProcesses.get(info.processName, info.uid) != null) {
2605                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2606                            + "/" + info.processName);
2607                    return null;
2608                }
2609            } else {
2610                // When the user is explicitly starting a process, then clear its
2611                // crash count so that we won't make it bad until they see at
2612                // least one crash dialog again, and make the process good again
2613                // if it had been bad.
2614                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2615                        + "/" + info.processName);
2616                mProcessCrashTimes.remove(info.processName, info.uid);
2617                if (mBadProcesses.get(info.processName, info.uid) != null) {
2618                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2619                            UserHandle.getUserId(info.uid), info.uid,
2620                            info.processName);
2621                    mBadProcesses.remove(info.processName, info.uid);
2622                    if (app != null) {
2623                        app.bad = false;
2624                    }
2625                }
2626            }
2627        }
2628
2629        if (app == null) {
2630            app = newProcessRecordLocked(info, processName, isolated);
2631            if (app == null) {
2632                Slog.w(TAG, "Failed making new process record for "
2633                        + processName + "/" + info.uid + " isolated=" + isolated);
2634                return null;
2635            }
2636            mProcessNames.put(processName, app.uid, app);
2637            if (isolated) {
2638                mIsolatedProcesses.put(app.uid, app);
2639            }
2640        } else {
2641            // If this is a new package in the process, add the package to the list
2642            app.addPackage(info.packageName, mProcessStats);
2643        }
2644
2645        // If the system is not ready yet, then hold off on starting this
2646        // process until it is.
2647        if (!mProcessesReady
2648                && !isAllowedWhileBooting(info)
2649                && !allowWhileBooting) {
2650            if (!mProcessesOnHold.contains(app)) {
2651                mProcessesOnHold.add(app);
2652            }
2653            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2654            return app;
2655        }
2656
2657        startProcessLocked(app, hostingType, hostingNameStr);
2658        return (app.pid != 0) ? app : null;
2659    }
2660
2661    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2662        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2663    }
2664
2665    private final void startProcessLocked(ProcessRecord app,
2666            String hostingType, String hostingNameStr) {
2667        if (app.pid > 0 && app.pid != MY_PID) {
2668            synchronized (mPidsSelfLocked) {
2669                mPidsSelfLocked.remove(app.pid);
2670                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2671            }
2672            app.setPid(0);
2673        }
2674
2675        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2676                "startProcessLocked removing on hold: " + app);
2677        mProcessesOnHold.remove(app);
2678
2679        updateCpuStats();
2680
2681        try {
2682            int uid = app.uid;
2683
2684            int[] gids = null;
2685            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2686            if (!app.isolated) {
2687                int[] permGids = null;
2688                try {
2689                    final PackageManager pm = mContext.getPackageManager();
2690                    permGids = pm.getPackageGids(app.info.packageName);
2691
2692                    if (Environment.isExternalStorageEmulated()) {
2693                        if (pm.checkPermission(
2694                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2695                                app.info.packageName) == PERMISSION_GRANTED) {
2696                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2697                        } else {
2698                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2699                        }
2700                    }
2701                } catch (PackageManager.NameNotFoundException e) {
2702                    Slog.w(TAG, "Unable to retrieve gids", e);
2703                }
2704
2705                /*
2706                 * Add shared application GID so applications can share some
2707                 * resources like shared libraries
2708                 */
2709                if (permGids == null) {
2710                    gids = new int[1];
2711                } else {
2712                    gids = new int[permGids.length + 1];
2713                    System.arraycopy(permGids, 0, gids, 1, permGids.length);
2714                }
2715                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2716            }
2717            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2718                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2719                        && mTopComponent != null
2720                        && app.processName.equals(mTopComponent.getPackageName())) {
2721                    uid = 0;
2722                }
2723                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2724                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2725                    uid = 0;
2726                }
2727            }
2728            int debugFlags = 0;
2729            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2730                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2731                // Also turn on CheckJNI for debuggable apps. It's quite
2732                // awkward to turn on otherwise.
2733                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2734            }
2735            // Run the app in safe mode if its manifest requests so or the
2736            // system is booted in safe mode.
2737            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2738                Zygote.systemInSafeMode == true) {
2739                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2740            }
2741            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2742                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2743            }
2744            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2745                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2746            }
2747            if ("1".equals(SystemProperties.get("debug.assert"))) {
2748                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2749            }
2750
2751            // Start the process.  It will either succeed and return a result containing
2752            // the PID of the new process, or else throw a RuntimeException.
2753            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2754                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2755                    app.info.targetSdkVersion, app.info.seinfo, null);
2756
2757            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
2758            synchronized (bs) {
2759                if (bs.isOnBattery()) {
2760                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
2761                }
2762            }
2763
2764            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2765                    UserHandle.getUserId(uid), startResult.pid, uid,
2766                    app.processName, hostingType,
2767                    hostingNameStr != null ? hostingNameStr : "");
2768
2769            if (app.persistent) {
2770                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2771            }
2772
2773            StringBuilder buf = mStringBuilder;
2774            buf.setLength(0);
2775            buf.append("Start proc ");
2776            buf.append(app.processName);
2777            buf.append(" for ");
2778            buf.append(hostingType);
2779            if (hostingNameStr != null) {
2780                buf.append(" ");
2781                buf.append(hostingNameStr);
2782            }
2783            buf.append(": pid=");
2784            buf.append(startResult.pid);
2785            buf.append(" uid=");
2786            buf.append(uid);
2787            buf.append(" gids={");
2788            if (gids != null) {
2789                for (int gi=0; gi<gids.length; gi++) {
2790                    if (gi != 0) buf.append(", ");
2791                    buf.append(gids[gi]);
2792
2793                }
2794            }
2795            buf.append("}");
2796            Slog.i(TAG, buf.toString());
2797            app.setPid(startResult.pid);
2798            app.usingWrapper = startResult.usingWrapper;
2799            app.removed = false;
2800            synchronized (mPidsSelfLocked) {
2801                this.mPidsSelfLocked.put(startResult.pid, app);
2802                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2803                msg.obj = app;
2804                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2805                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2806            }
2807            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
2808                    app.processName, app.info.uid);
2809            if (app.isolated) {
2810                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2811            }
2812        } catch (RuntimeException e) {
2813            // XXX do better error recovery.
2814            app.setPid(0);
2815            Slog.e(TAG, "Failure starting process " + app.processName, e);
2816        }
2817    }
2818
2819    void updateUsageStats(ActivityRecord component, boolean resumed) {
2820        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
2821        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2822        if (resumed) {
2823            mUsageStatsService.noteResumeComponent(component.realActivity);
2824            synchronized (stats) {
2825                stats.noteActivityResumedLocked(component.app.uid);
2826            }
2827        } else {
2828            mUsageStatsService.notePauseComponent(component.realActivity);
2829            synchronized (stats) {
2830                stats.noteActivityPausedLocked(component.app.uid);
2831            }
2832        }
2833    }
2834
2835    Intent getHomeIntent() {
2836        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
2837        intent.setComponent(mTopComponent);
2838        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
2839            intent.addCategory(Intent.CATEGORY_HOME);
2840        }
2841        return intent;
2842    }
2843
2844    boolean startHomeActivityLocked(int userId) {
2845        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2846                && mTopAction == null) {
2847            // We are running in factory test mode, but unable to find
2848            // the factory test app, so just sit around displaying the
2849            // error message and don't try to start anything.
2850            return false;
2851        }
2852        Intent intent = getHomeIntent();
2853        ActivityInfo aInfo =
2854            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2855        if (aInfo != null) {
2856            intent.setComponent(new ComponentName(
2857                    aInfo.applicationInfo.packageName, aInfo.name));
2858            // Don't do this if the home app is currently being
2859            // instrumented.
2860            aInfo = new ActivityInfo(aInfo);
2861            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2862            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2863                    aInfo.applicationInfo.uid, true);
2864            if (app == null || app.instrumentationClass == null) {
2865                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2866                mStackSupervisor.startHomeActivity(intent, aInfo);
2867            }
2868        }
2869
2870        return true;
2871    }
2872
2873    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2874        ActivityInfo ai = null;
2875        ComponentName comp = intent.getComponent();
2876        try {
2877            if (comp != null) {
2878                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2879            } else {
2880                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2881                        intent,
2882                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2883                            flags, userId);
2884
2885                if (info != null) {
2886                    ai = info.activityInfo;
2887                }
2888            }
2889        } catch (RemoteException e) {
2890            // ignore
2891        }
2892
2893        return ai;
2894    }
2895
2896    /**
2897     * Starts the "new version setup screen" if appropriate.
2898     */
2899    void startSetupActivityLocked() {
2900        // Only do this once per boot.
2901        if (mCheckedForSetup) {
2902            return;
2903        }
2904
2905        // We will show this screen if the current one is a different
2906        // version than the last one shown, and we are not running in
2907        // low-level factory test mode.
2908        final ContentResolver resolver = mContext.getContentResolver();
2909        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
2910                Settings.Global.getInt(resolver,
2911                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2912            mCheckedForSetup = true;
2913
2914            // See if we should be showing the platform update setup UI.
2915            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2916            List<ResolveInfo> ris = mContext.getPackageManager()
2917                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2918
2919            // We don't allow third party apps to replace this.
2920            ResolveInfo ri = null;
2921            for (int i=0; ris != null && i<ris.size(); i++) {
2922                if ((ris.get(i).activityInfo.applicationInfo.flags
2923                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
2924                    ri = ris.get(i);
2925                    break;
2926                }
2927            }
2928
2929            if (ri != null) {
2930                String vers = ri.activityInfo.metaData != null
2931                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2932                        : null;
2933                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2934                    vers = ri.activityInfo.applicationInfo.metaData.getString(
2935                            Intent.METADATA_SETUP_VERSION);
2936                }
2937                String lastVers = Settings.Secure.getString(
2938                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
2939                if (vers != null && !vers.equals(lastVers)) {
2940                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2941                    intent.setComponent(new ComponentName(
2942                            ri.activityInfo.packageName, ri.activityInfo.name));
2943                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
2944                            null, null, 0, 0, 0, null, 0, null, false, null, null);
2945                }
2946            }
2947        }
2948    }
2949
2950    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2951        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2952    }
2953
2954    void enforceNotIsolatedCaller(String caller) {
2955        if (UserHandle.isIsolated(Binder.getCallingUid())) {
2956            throw new SecurityException("Isolated process not allowed to call " + caller);
2957        }
2958    }
2959
2960    @Override
2961    public int getFrontActivityScreenCompatMode() {
2962        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2963        synchronized (this) {
2964            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2965        }
2966    }
2967
2968    @Override
2969    public void setFrontActivityScreenCompatMode(int mode) {
2970        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2971                "setFrontActivityScreenCompatMode");
2972        synchronized (this) {
2973            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2974        }
2975    }
2976
2977    @Override
2978    public int getPackageScreenCompatMode(String packageName) {
2979        enforceNotIsolatedCaller("getPackageScreenCompatMode");
2980        synchronized (this) {
2981            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2982        }
2983    }
2984
2985    @Override
2986    public void setPackageScreenCompatMode(String packageName, int mode) {
2987        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2988                "setPackageScreenCompatMode");
2989        synchronized (this) {
2990            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2991        }
2992    }
2993
2994    @Override
2995    public boolean getPackageAskScreenCompat(String packageName) {
2996        enforceNotIsolatedCaller("getPackageAskScreenCompat");
2997        synchronized (this) {
2998            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2999        }
3000    }
3001
3002    @Override
3003    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3004        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3005                "setPackageAskScreenCompat");
3006        synchronized (this) {
3007            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3008        }
3009    }
3010
3011    private void dispatchProcessesChanged() {
3012        int N;
3013        synchronized (this) {
3014            N = mPendingProcessChanges.size();
3015            if (mActiveProcessChanges.length < N) {
3016                mActiveProcessChanges = new ProcessChangeItem[N];
3017            }
3018            mPendingProcessChanges.toArray(mActiveProcessChanges);
3019            mAvailProcessChanges.addAll(mPendingProcessChanges);
3020            mPendingProcessChanges.clear();
3021            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3022        }
3023
3024        int i = mProcessObservers.beginBroadcast();
3025        while (i > 0) {
3026            i--;
3027            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3028            if (observer != null) {
3029                try {
3030                    for (int j=0; j<N; j++) {
3031                        ProcessChangeItem item = mActiveProcessChanges[j];
3032                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3033                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3034                                    + item.pid + " uid=" + item.uid + ": "
3035                                    + item.foregroundActivities);
3036                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3037                                    item.foregroundActivities);
3038                        }
3039                        if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
3040                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
3041                                    + item.pid + " uid=" + item.uid + ": " + item.importance);
3042                            observer.onImportanceChanged(item.pid, item.uid,
3043                                    item.importance);
3044                        }
3045                    }
3046                } catch (RemoteException e) {
3047                }
3048            }
3049        }
3050        mProcessObservers.finishBroadcast();
3051    }
3052
3053    private void dispatchProcessDied(int pid, int uid) {
3054        int i = mProcessObservers.beginBroadcast();
3055        while (i > 0) {
3056            i--;
3057            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3058            if (observer != null) {
3059                try {
3060                    observer.onProcessDied(pid, uid);
3061                } catch (RemoteException e) {
3062                }
3063            }
3064        }
3065        mProcessObservers.finishBroadcast();
3066    }
3067
3068    final void doPendingActivityLaunchesLocked(boolean doResume) {
3069        final int N = mPendingActivityLaunches.size();
3070        if (N <= 0) {
3071            return;
3072        }
3073        for (int i=0; i<N; i++) {
3074            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3075            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
3076                    doResume && i == (N-1), null);
3077        }
3078        mPendingActivityLaunches.clear();
3079    }
3080
3081    @Override
3082    public final int startActivity(IApplicationThread caller, String callingPackage,
3083            Intent intent, String resolvedType, IBinder resultTo,
3084            String resultWho, int requestCode, int startFlags,
3085            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3086        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3087                resultWho, requestCode,
3088                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3089    }
3090
3091    @Override
3092    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3093            Intent intent, String resolvedType, IBinder resultTo,
3094            String resultWho, int requestCode, int startFlags,
3095            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3096        enforceNotIsolatedCaller("startActivity");
3097        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3098                false, true, "startActivity", null);
3099        // TODO: Switch to user app stacks here.
3100        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3101                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3102                null, null, options, userId, null);
3103    }
3104
3105    @Override
3106    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3107            Intent intent, String resolvedType, IBinder resultTo,
3108            String resultWho, int requestCode, int startFlags, String profileFile,
3109            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3110        enforceNotIsolatedCaller("startActivityAndWait");
3111        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3112                false, true, "startActivityAndWait", null);
3113        WaitResult res = new WaitResult();
3114        // TODO: Switch to user app stacks here.
3115        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3116                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3117                res, null, options, UserHandle.getCallingUserId(), null);
3118        return res;
3119    }
3120
3121    @Override
3122    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3123            Intent intent, String resolvedType, IBinder resultTo,
3124            String resultWho, int requestCode, int startFlags, Configuration config,
3125            Bundle options, int userId) {
3126        enforceNotIsolatedCaller("startActivityWithConfig");
3127        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3128                false, true, "startActivityWithConfig", null);
3129        // TODO: Switch to user app stacks here.
3130        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3131                resolvedType, resultTo, resultWho, requestCode, startFlags,
3132                null, null, null, config, options, userId, null);
3133        return ret;
3134    }
3135
3136    @Override
3137    public int startActivityIntentSender(IApplicationThread caller,
3138            IntentSender intent, Intent fillInIntent, String resolvedType,
3139            IBinder resultTo, String resultWho, int requestCode,
3140            int flagsMask, int flagsValues, Bundle options) {
3141        enforceNotIsolatedCaller("startActivityIntentSender");
3142        // Refuse possible leaked file descriptors
3143        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3144            throw new IllegalArgumentException("File descriptors passed in Intent");
3145        }
3146
3147        IIntentSender sender = intent.getTarget();
3148        if (!(sender instanceof PendingIntentRecord)) {
3149            throw new IllegalArgumentException("Bad PendingIntent object");
3150        }
3151
3152        PendingIntentRecord pir = (PendingIntentRecord)sender;
3153
3154        synchronized (this) {
3155            // If this is coming from the currently resumed activity, it is
3156            // effectively saying that app switches are allowed at this point.
3157            final ActivityStack stack = getFocusedStack();
3158            if (stack.mResumedActivity != null &&
3159                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3160                mAppSwitchesAllowedTime = 0;
3161            }
3162        }
3163        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3164                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3165        return ret;
3166    }
3167
3168    @Override
3169    public boolean startNextMatchingActivity(IBinder callingActivity,
3170            Intent intent, Bundle options) {
3171        // Refuse possible leaked file descriptors
3172        if (intent != null && intent.hasFileDescriptors() == true) {
3173            throw new IllegalArgumentException("File descriptors passed in Intent");
3174        }
3175
3176        synchronized (this) {
3177            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3178            if (r == null) {
3179                ActivityOptions.abort(options);
3180                return false;
3181            }
3182            if (r.app == null || r.app.thread == null) {
3183                // The caller is not running...  d'oh!
3184                ActivityOptions.abort(options);
3185                return false;
3186            }
3187            intent = new Intent(intent);
3188            // The caller is not allowed to change the data.
3189            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3190            // And we are resetting to find the next component...
3191            intent.setComponent(null);
3192
3193            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3194
3195            ActivityInfo aInfo = null;
3196            try {
3197                List<ResolveInfo> resolves =
3198                    AppGlobals.getPackageManager().queryIntentActivities(
3199                            intent, r.resolvedType,
3200                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3201                            UserHandle.getCallingUserId());
3202
3203                // Look for the original activity in the list...
3204                final int N = resolves != null ? resolves.size() : 0;
3205                for (int i=0; i<N; i++) {
3206                    ResolveInfo rInfo = resolves.get(i);
3207                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3208                            && rInfo.activityInfo.name.equals(r.info.name)) {
3209                        // We found the current one...  the next matching is
3210                        // after it.
3211                        i++;
3212                        if (i<N) {
3213                            aInfo = resolves.get(i).activityInfo;
3214                        }
3215                        if (debug) {
3216                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3217                                    + "/" + r.info.name);
3218                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3219                                    + "/" + aInfo.name);
3220                        }
3221                        break;
3222                    }
3223                }
3224            } catch (RemoteException e) {
3225            }
3226
3227            if (aInfo == null) {
3228                // Nobody who is next!
3229                ActivityOptions.abort(options);
3230                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3231                return false;
3232            }
3233
3234            intent.setComponent(new ComponentName(
3235                    aInfo.applicationInfo.packageName, aInfo.name));
3236            intent.setFlags(intent.getFlags()&~(
3237                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3238                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3239                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3240                    Intent.FLAG_ACTIVITY_NEW_TASK));
3241
3242            // Okay now we need to start the new activity, replacing the
3243            // currently running activity.  This is a little tricky because
3244            // we want to start the new one as if the current one is finished,
3245            // but not finish the current one first so that there is no flicker.
3246            // And thus...
3247            final boolean wasFinishing = r.finishing;
3248            r.finishing = true;
3249
3250            // Propagate reply information over to the new activity.
3251            final ActivityRecord resultTo = r.resultTo;
3252            final String resultWho = r.resultWho;
3253            final int requestCode = r.requestCode;
3254            r.resultTo = null;
3255            if (resultTo != null) {
3256                resultTo.removeResultsLocked(r, resultWho, requestCode);
3257            }
3258
3259            final long origId = Binder.clearCallingIdentity();
3260            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3261                    r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
3262                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3263                    options, false, null, null);
3264            Binder.restoreCallingIdentity(origId);
3265
3266            r.finishing = wasFinishing;
3267            if (res != ActivityManager.START_SUCCESS) {
3268                return false;
3269            }
3270            return true;
3271        }
3272    }
3273
3274    final int startActivityInPackage(int uid, String callingPackage,
3275            Intent intent, String resolvedType, IBinder resultTo,
3276            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3277                    IActivityContainer container) {
3278
3279        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3280                false, true, "startActivityInPackage", null);
3281
3282        // TODO: Switch to user app stacks here.
3283        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3284                resultTo, resultWho, requestCode, startFlags,
3285                null, null, null, null, options, userId, container);
3286        return ret;
3287    }
3288
3289    @Override
3290    public final int startActivities(IApplicationThread caller, String callingPackage,
3291            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3292            int userId) {
3293        enforceNotIsolatedCaller("startActivities");
3294        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3295                false, true, "startActivity", null);
3296        // TODO: Switch to user app stacks here.
3297        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3298                resolvedTypes, resultTo, options, userId);
3299        return ret;
3300    }
3301
3302    final int startActivitiesInPackage(int uid, String callingPackage,
3303            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3304            Bundle options, int userId) {
3305
3306        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3307                false, true, "startActivityInPackage", null);
3308        // TODO: Switch to user app stacks here.
3309        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3310                resultTo, options, userId);
3311        return ret;
3312    }
3313
3314    final void addRecentTaskLocked(TaskRecord task) {
3315        int N = mRecentTasks.size();
3316        // Quick case: check if the top-most recent task is the same.
3317        if (N > 0 && mRecentTasks.get(0) == task) {
3318            return;
3319        }
3320        // Remove any existing entries that are the same kind of task.
3321        for (int i=0; i<N; i++) {
3322            TaskRecord tr = mRecentTasks.get(i);
3323            if (task.userId == tr.userId
3324                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
3325                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
3326                tr.disposeThumbnail();
3327                mRecentTasks.remove(i);
3328                i--;
3329                N--;
3330                if (task.intent == null) {
3331                    // If the new recent task we are adding is not fully
3332                    // specified, then replace it with the existing recent task.
3333                    task = tr;
3334                }
3335            }
3336        }
3337        if (N >= MAX_RECENT_TASKS) {
3338            mRecentTasks.remove(N-1).disposeThumbnail();
3339        }
3340        mRecentTasks.add(0, task);
3341    }
3342
3343    @Override
3344    public void reportActivityFullyDrawn(IBinder token) {
3345        synchronized (this) {
3346            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3347            if (r == null) {
3348                return;
3349            }
3350            r.reportFullyDrawnLocked();
3351        }
3352    }
3353
3354    @Override
3355    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3356        synchronized (this) {
3357            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3358            if (r == null) {
3359                return;
3360            }
3361            final long origId = Binder.clearCallingIdentity();
3362            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3363            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3364                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3365            if (config != null) {
3366                r.frozenBeforeDestroy = true;
3367                if (!updateConfigurationLocked(config, r, false, false)) {
3368                    mStackSupervisor.resumeTopActivitiesLocked();
3369                }
3370            }
3371            Binder.restoreCallingIdentity(origId);
3372        }
3373    }
3374
3375    @Override
3376    public int getRequestedOrientation(IBinder token) {
3377        synchronized (this) {
3378            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3379            if (r == null) {
3380                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3381            }
3382            return mWindowManager.getAppOrientation(r.appToken);
3383        }
3384    }
3385
3386    /**
3387     * This is the internal entry point for handling Activity.finish().
3388     *
3389     * @param token The Binder token referencing the Activity we want to finish.
3390     * @param resultCode Result code, if any, from this Activity.
3391     * @param resultData Result data (Intent), if any, from this Activity.
3392     *
3393     * @return Returns true if the activity successfully finished, or false if it is still running.
3394     */
3395    @Override
3396    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
3397        // Refuse possible leaked file descriptors
3398        if (resultData != null && resultData.hasFileDescriptors() == true) {
3399            throw new IllegalArgumentException("File descriptors passed in Intent");
3400        }
3401
3402        synchronized(this) {
3403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3404            if (r == null) {
3405                return true;
3406            }
3407            if (mController != null) {
3408                // Find the first activity that is not finishing.
3409                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3410                if (next != null) {
3411                    // ask watcher if this is allowed
3412                    boolean resumeOK = true;
3413                    try {
3414                        resumeOK = mController.activityResuming(next.packageName);
3415                    } catch (RemoteException e) {
3416                        mController = null;
3417                        Watchdog.getInstance().setActivityController(null);
3418                    }
3419
3420                    if (!resumeOK) {
3421                        return false;
3422                    }
3423                }
3424            }
3425            final long origId = Binder.clearCallingIdentity();
3426            boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
3427                    resultData, "app-request", true);
3428            Binder.restoreCallingIdentity(origId);
3429            return res;
3430        }
3431    }
3432
3433    @Override
3434    public final void finishHeavyWeightApp() {
3435        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3436                != PackageManager.PERMISSION_GRANTED) {
3437            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3438                    + Binder.getCallingPid()
3439                    + ", uid=" + Binder.getCallingUid()
3440                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3441            Slog.w(TAG, msg);
3442            throw new SecurityException(msg);
3443        }
3444
3445        synchronized(this) {
3446            if (mHeavyWeightProcess == null) {
3447                return;
3448            }
3449
3450            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3451                    mHeavyWeightProcess.activities);
3452            for (int i=0; i<activities.size(); i++) {
3453                ActivityRecord r = activities.get(i);
3454                if (!r.finishing) {
3455                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3456                            null, "finish-heavy", true);
3457                }
3458            }
3459
3460            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3461                    mHeavyWeightProcess.userId, 0));
3462            mHeavyWeightProcess = null;
3463        }
3464    }
3465
3466    @Override
3467    public void crashApplication(int uid, int initialPid, String packageName,
3468            String message) {
3469        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3470                != PackageManager.PERMISSION_GRANTED) {
3471            String msg = "Permission Denial: crashApplication() from pid="
3472                    + Binder.getCallingPid()
3473                    + ", uid=" + Binder.getCallingUid()
3474                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3475            Slog.w(TAG, msg);
3476            throw new SecurityException(msg);
3477        }
3478
3479        synchronized(this) {
3480            ProcessRecord proc = null;
3481
3482            // Figure out which process to kill.  We don't trust that initialPid
3483            // still has any relation to current pids, so must scan through the
3484            // list.
3485            synchronized (mPidsSelfLocked) {
3486                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3487                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3488                    if (p.uid != uid) {
3489                        continue;
3490                    }
3491                    if (p.pid == initialPid) {
3492                        proc = p;
3493                        break;
3494                    }
3495                    if (p.pkgList.containsKey(packageName)) {
3496                        proc = p;
3497                    }
3498                }
3499            }
3500
3501            if (proc == null) {
3502                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3503                        + " initialPid=" + initialPid
3504                        + " packageName=" + packageName);
3505                return;
3506            }
3507
3508            if (proc.thread != null) {
3509                if (proc.pid == Process.myPid()) {
3510                    Log.w(TAG, "crashApplication: trying to crash self!");
3511                    return;
3512                }
3513                long ident = Binder.clearCallingIdentity();
3514                try {
3515                    proc.thread.scheduleCrash(message);
3516                } catch (RemoteException e) {
3517                }
3518                Binder.restoreCallingIdentity(ident);
3519            }
3520        }
3521    }
3522
3523    @Override
3524    public final void finishSubActivity(IBinder token, String resultWho,
3525            int requestCode) {
3526        synchronized(this) {
3527            final long origId = Binder.clearCallingIdentity();
3528            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3529            if (r != null) {
3530                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3531            }
3532            Binder.restoreCallingIdentity(origId);
3533        }
3534    }
3535
3536    @Override
3537    public boolean finishActivityAffinity(IBinder token) {
3538        synchronized(this) {
3539            final long origId = Binder.clearCallingIdentity();
3540            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3541            boolean res = false;
3542            if (r != null) {
3543                res = r.task.stack.finishActivityAffinityLocked(r);
3544            }
3545            Binder.restoreCallingIdentity(origId);
3546            return res;
3547        }
3548    }
3549
3550    @Override
3551    public boolean willActivityBeVisible(IBinder token) {
3552        synchronized(this) {
3553            ActivityStack stack = ActivityRecord.getStackLocked(token);
3554            if (stack != null) {
3555                return stack.willActivityBeVisibleLocked(token);
3556            }
3557            return false;
3558        }
3559    }
3560
3561    @Override
3562    public void overridePendingTransition(IBinder token, String packageName,
3563            int enterAnim, int exitAnim) {
3564        synchronized(this) {
3565            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3566            if (self == null) {
3567                return;
3568            }
3569
3570            final long origId = Binder.clearCallingIdentity();
3571
3572            if (self.state == ActivityState.RESUMED
3573                    || self.state == ActivityState.PAUSING) {
3574                mWindowManager.overridePendingAppTransition(packageName,
3575                        enterAnim, exitAnim, null);
3576            }
3577
3578            Binder.restoreCallingIdentity(origId);
3579        }
3580    }
3581
3582    /**
3583     * Main function for removing an existing process from the activity manager
3584     * as a result of that process going away.  Clears out all connections
3585     * to the process.
3586     */
3587    private final void handleAppDiedLocked(ProcessRecord app,
3588            boolean restarting, boolean allowRestart) {
3589        int pid = app.pid;
3590        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3591        if (!restarting) {
3592            removeLruProcessLocked(app);
3593            if (pid > 0) {
3594                ProcessList.remove(pid);
3595            }
3596        }
3597
3598        if (mProfileProc == app) {
3599            clearProfilerLocked();
3600        }
3601
3602        // Remove this application's activities from active lists.
3603        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3604
3605        app.activities.clear();
3606
3607        if (app.instrumentationClass != null) {
3608            Slog.w(TAG, "Crash of app " + app.processName
3609                  + " running instrumentation " + app.instrumentationClass);
3610            Bundle info = new Bundle();
3611            info.putString("shortMsg", "Process crashed.");
3612            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3613        }
3614
3615        if (!restarting) {
3616            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3617                // If there was nothing to resume, and we are not already
3618                // restarting this process, but there is a visible activity that
3619                // is hosted by the process...  then make sure all visible
3620                // activities are running, taking care of restarting this
3621                // process.
3622                if (hasVisibleActivities) {
3623                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3624                }
3625            }
3626        }
3627    }
3628
3629    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3630        IBinder threadBinder = thread.asBinder();
3631        // Find the application record.
3632        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3633            ProcessRecord rec = mLruProcesses.get(i);
3634            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3635                return i;
3636            }
3637        }
3638        return -1;
3639    }
3640
3641    final ProcessRecord getRecordForAppLocked(
3642            IApplicationThread thread) {
3643        if (thread == null) {
3644            return null;
3645        }
3646
3647        int appIndex = getLRURecordIndexForAppLocked(thread);
3648        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3649    }
3650
3651    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3652        // If there are no longer any background processes running,
3653        // and the app that died was not running instrumentation,
3654        // then tell everyone we are now low on memory.
3655        boolean haveBg = false;
3656        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3657            ProcessRecord rec = mLruProcesses.get(i);
3658            if (rec.thread != null
3659                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
3660                haveBg = true;
3661                break;
3662            }
3663        }
3664
3665        if (!haveBg) {
3666            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
3667            if (doReport) {
3668                long now = SystemClock.uptimeMillis();
3669                if (now < (mLastMemUsageReportTime+5*60*1000)) {
3670                    doReport = false;
3671                } else {
3672                    mLastMemUsageReportTime = now;
3673                }
3674            }
3675            final ArrayList<ProcessMemInfo> memInfos
3676                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
3677            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3678            long now = SystemClock.uptimeMillis();
3679            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3680                ProcessRecord rec = mLruProcesses.get(i);
3681                if (rec == dyingProc || rec.thread == null) {
3682                    continue;
3683                }
3684                if (doReport) {
3685                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
3686                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
3687                }
3688                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3689                    // The low memory report is overriding any current
3690                    // state for a GC request.  Make sure to do
3691                    // heavy/important/visible/foreground processes first.
3692                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3693                        rec.lastRequestedGc = 0;
3694                    } else {
3695                        rec.lastRequestedGc = rec.lastLowMemory;
3696                    }
3697                    rec.reportLowMemory = true;
3698                    rec.lastLowMemory = now;
3699                    mProcessesToGc.remove(rec);
3700                    addProcessToGcListLocked(rec);
3701                }
3702            }
3703            if (doReport) {
3704                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
3705                mHandler.sendMessage(msg);
3706            }
3707            scheduleAppGcsLocked();
3708        }
3709    }
3710
3711    final void appDiedLocked(ProcessRecord app, int pid,
3712            IApplicationThread thread) {
3713
3714        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3715        synchronized (stats) {
3716            stats.noteProcessDiedLocked(app.info.uid, pid);
3717        }
3718
3719        // Clean up already done if the process has been re-started.
3720        if (app.pid == pid && app.thread != null &&
3721                app.thread.asBinder() == thread.asBinder()) {
3722            boolean doLowMem = app.instrumentationClass == null;
3723            boolean doOomAdj = doLowMem;
3724            if (!app.killedByAm) {
3725                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3726                        + ") has died.");
3727                mAllowLowerMemLevel = true;
3728            } else {
3729                // Note that we always want to do oom adj to update our state with the
3730                // new number of procs.
3731                mAllowLowerMemLevel = false;
3732                doLowMem = false;
3733            }
3734            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3735            if (DEBUG_CLEANUP) Slog.v(
3736                TAG, "Dying app: " + app + ", pid: " + pid
3737                + ", thread: " + thread.asBinder());
3738            handleAppDiedLocked(app, false, true);
3739
3740            if (doOomAdj) {
3741                updateOomAdjLocked();
3742            }
3743            if (doLowMem) {
3744                doLowMemReportIfNeededLocked(app);
3745            }
3746        } else if (app.pid != pid) {
3747            // A new process has already been started.
3748            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3749                    + ") has died and restarted (pid " + app.pid + ").");
3750            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3751        } else if (DEBUG_PROCESSES) {
3752            Slog.d(TAG, "Received spurious death notification for thread "
3753                    + thread.asBinder());
3754        }
3755    }
3756
3757    /**
3758     * If a stack trace dump file is configured, dump process stack traces.
3759     * @param clearTraces causes the dump file to be erased prior to the new
3760     *    traces being written, if true; when false, the new traces will be
3761     *    appended to any existing file content.
3762     * @param firstPids of dalvik VM processes to dump stack traces for first
3763     * @param lastPids of dalvik VM processes to dump stack traces for last
3764     * @param nativeProcs optional list of native process names to dump stack crawls
3765     * @return file containing stack traces, or null if no dump file is configured
3766     */
3767    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3768            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3769        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3770        if (tracesPath == null || tracesPath.length() == 0) {
3771            return null;
3772        }
3773
3774        File tracesFile = new File(tracesPath);
3775        try {
3776            File tracesDir = tracesFile.getParentFile();
3777            if (!tracesDir.exists()) {
3778                tracesFile.mkdirs();
3779                if (!SELinux.restorecon(tracesDir)) {
3780                    return null;
3781                }
3782            }
3783            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3784
3785            if (clearTraces && tracesFile.exists()) tracesFile.delete();
3786            tracesFile.createNewFile();
3787            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3788        } catch (IOException e) {
3789            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3790            return null;
3791        }
3792
3793        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
3794        return tracesFile;
3795    }
3796
3797    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3798            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3799        // Use a FileObserver to detect when traces finish writing.
3800        // The order of traces is considered important to maintain for legibility.
3801        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3802            @Override
3803            public synchronized void onEvent(int event, String path) { notify(); }
3804        };
3805
3806        try {
3807            observer.startWatching();
3808
3809            // First collect all of the stacks of the most important pids.
3810            if (firstPids != null) {
3811                try {
3812                    int num = firstPids.size();
3813                    for (int i = 0; i < num; i++) {
3814                        synchronized (observer) {
3815                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3816                            observer.wait(200);  // Wait for write-close, give up after 200msec
3817                        }
3818                    }
3819                } catch (InterruptedException e) {
3820                    Log.wtf(TAG, e);
3821                }
3822            }
3823
3824            // Next collect the stacks of the native pids
3825            if (nativeProcs != null) {
3826                int[] pids = Process.getPidsForCommands(nativeProcs);
3827                if (pids != null) {
3828                    for (int pid : pids) {
3829                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3830                    }
3831                }
3832            }
3833
3834            // Lastly, measure CPU usage.
3835            if (processCpuTracker != null) {
3836                processCpuTracker.init();
3837                System.gc();
3838                processCpuTracker.update();
3839                try {
3840                    synchronized (processCpuTracker) {
3841                        processCpuTracker.wait(500); // measure over 1/2 second.
3842                    }
3843                } catch (InterruptedException e) {
3844                }
3845                processCpuTracker.update();
3846
3847                // We'll take the stack crawls of just the top apps using CPU.
3848                final int N = processCpuTracker.countWorkingStats();
3849                int numProcs = 0;
3850                for (int i=0; i<N && numProcs<5; i++) {
3851                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
3852                    if (lastPids.indexOfKey(stats.pid) >= 0) {
3853                        numProcs++;
3854                        try {
3855                            synchronized (observer) {
3856                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3857                                observer.wait(200);  // Wait for write-close, give up after 200msec
3858                            }
3859                        } catch (InterruptedException e) {
3860                            Log.wtf(TAG, e);
3861                        }
3862
3863                    }
3864                }
3865            }
3866        } finally {
3867            observer.stopWatching();
3868        }
3869    }
3870
3871    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3872        if (true || IS_USER_BUILD) {
3873            return;
3874        }
3875        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3876        if (tracesPath == null || tracesPath.length() == 0) {
3877            return;
3878        }
3879
3880        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3881        StrictMode.allowThreadDiskWrites();
3882        try {
3883            final File tracesFile = new File(tracesPath);
3884            final File tracesDir = tracesFile.getParentFile();
3885            final File tracesTmp = new File(tracesDir, "__tmp__");
3886            try {
3887                if (!tracesDir.exists()) {
3888                    tracesFile.mkdirs();
3889                    if (!SELinux.restorecon(tracesDir.getPath())) {
3890                        return;
3891                    }
3892                }
3893                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
3894
3895                if (tracesFile.exists()) {
3896                    tracesTmp.delete();
3897                    tracesFile.renameTo(tracesTmp);
3898                }
3899                StringBuilder sb = new StringBuilder();
3900                Time tobj = new Time();
3901                tobj.set(System.currentTimeMillis());
3902                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3903                sb.append(": ");
3904                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3905                sb.append(" since ");
3906                sb.append(msg);
3907                FileOutputStream fos = new FileOutputStream(tracesFile);
3908                fos.write(sb.toString().getBytes());
3909                if (app == null) {
3910                    fos.write("\n*** No application process!".getBytes());
3911                }
3912                fos.close();
3913                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3914            } catch (IOException e) {
3915                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3916                return;
3917            }
3918
3919            if (app != null) {
3920                ArrayList<Integer> firstPids = new ArrayList<Integer>();
3921                firstPids.add(app.pid);
3922                dumpStackTraces(tracesPath, firstPids, null, null, null);
3923            }
3924
3925            File lastTracesFile = null;
3926            File curTracesFile = null;
3927            for (int i=9; i>=0; i--) {
3928                String name = String.format(Locale.US, "slow%02d.txt", i);
3929                curTracesFile = new File(tracesDir, name);
3930                if (curTracesFile.exists()) {
3931                    if (lastTracesFile != null) {
3932                        curTracesFile.renameTo(lastTracesFile);
3933                    } else {
3934                        curTracesFile.delete();
3935                    }
3936                }
3937                lastTracesFile = curTracesFile;
3938            }
3939            tracesFile.renameTo(curTracesFile);
3940            if (tracesTmp.exists()) {
3941                tracesTmp.renameTo(tracesFile);
3942            }
3943        } finally {
3944            StrictMode.setThreadPolicy(oldPolicy);
3945        }
3946    }
3947
3948    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3949            ActivityRecord parent, boolean aboveSystem, final String annotation) {
3950        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3951        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3952
3953        if (mController != null) {
3954            try {
3955                // 0 == continue, -1 = kill process immediately
3956                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3957                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3958            } catch (RemoteException e) {
3959                mController = null;
3960                Watchdog.getInstance().setActivityController(null);
3961            }
3962        }
3963
3964        long anrTime = SystemClock.uptimeMillis();
3965        if (MONITOR_CPU_USAGE) {
3966            updateCpuStatsNow();
3967        }
3968
3969        synchronized (this) {
3970            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3971            if (mShuttingDown) {
3972                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3973                return;
3974            } else if (app.notResponding) {
3975                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3976                return;
3977            } else if (app.crashing) {
3978                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3979                return;
3980            }
3981
3982            // In case we come through here for the same app before completing
3983            // this one, mark as anring now so we will bail out.
3984            app.notResponding = true;
3985
3986            // Log the ANR to the event log.
3987            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3988                    app.processName, app.info.flags, annotation);
3989
3990            // Dump thread traces as quickly as we can, starting with "interesting" processes.
3991            firstPids.add(app.pid);
3992
3993            int parentPid = app.pid;
3994            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3995            if (parentPid != app.pid) firstPids.add(parentPid);
3996
3997            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3998
3999            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4000                ProcessRecord r = mLruProcesses.get(i);
4001                if (r != null && r.thread != null) {
4002                    int pid = r.pid;
4003                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4004                        if (r.persistent) {
4005                            firstPids.add(pid);
4006                        } else {
4007                            lastPids.put(pid, Boolean.TRUE);
4008                        }
4009                    }
4010                }
4011            }
4012        }
4013
4014        // Log the ANR to the main log.
4015        StringBuilder info = new StringBuilder();
4016        info.setLength(0);
4017        info.append("ANR in ").append(app.processName);
4018        if (activity != null && activity.shortComponentName != null) {
4019            info.append(" (").append(activity.shortComponentName).append(")");
4020        }
4021        info.append("\n");
4022        info.append("PID: ").append(app.pid).append("\n");
4023        if (annotation != null) {
4024            info.append("Reason: ").append(annotation).append("\n");
4025        }
4026        if (parent != null && parent != activity) {
4027            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4028        }
4029
4030        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4031
4032        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4033                NATIVE_STACKS_OF_INTEREST);
4034
4035        String cpuInfo = null;
4036        if (MONITOR_CPU_USAGE) {
4037            updateCpuStatsNow();
4038            synchronized (mProcessCpuThread) {
4039                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4040            }
4041            info.append(processCpuTracker.printCurrentLoad());
4042            info.append(cpuInfo);
4043        }
4044
4045        info.append(processCpuTracker.printCurrentState(anrTime));
4046
4047        Slog.e(TAG, info.toString());
4048        if (tracesFile == null) {
4049            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4050            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4051        }
4052
4053        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4054                cpuInfo, tracesFile, null);
4055
4056        if (mController != null) {
4057            try {
4058                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4059                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4060                if (res != 0) {
4061                    if (res < 0 && app.pid != MY_PID) {
4062                        Process.killProcess(app.pid);
4063                    } else {
4064                        synchronized (this) {
4065                            mServices.scheduleServiceTimeoutLocked(app);
4066                        }
4067                    }
4068                    return;
4069                }
4070            } catch (RemoteException e) {
4071                mController = null;
4072                Watchdog.getInstance().setActivityController(null);
4073            }
4074        }
4075
4076        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4077        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4078                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4079
4080        synchronized (this) {
4081            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4082                killUnneededProcessLocked(app, "background ANR");
4083                return;
4084            }
4085
4086            // Set the app's notResponding state, and look up the errorReportReceiver
4087            makeAppNotRespondingLocked(app,
4088                    activity != null ? activity.shortComponentName : null,
4089                    annotation != null ? "ANR " + annotation : "ANR",
4090                    info.toString());
4091
4092            // Bring up the infamous App Not Responding dialog
4093            Message msg = Message.obtain();
4094            HashMap<String, Object> map = new HashMap<String, Object>();
4095            msg.what = SHOW_NOT_RESPONDING_MSG;
4096            msg.obj = map;
4097            msg.arg1 = aboveSystem ? 1 : 0;
4098            map.put("app", app);
4099            if (activity != null) {
4100                map.put("activity", activity);
4101            }
4102
4103            mHandler.sendMessage(msg);
4104        }
4105    }
4106
4107    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4108        if (!mLaunchWarningShown) {
4109            mLaunchWarningShown = true;
4110            mHandler.post(new Runnable() {
4111                @Override
4112                public void run() {
4113                    synchronized (ActivityManagerService.this) {
4114                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4115                        d.show();
4116                        mHandler.postDelayed(new Runnable() {
4117                            @Override
4118                            public void run() {
4119                                synchronized (ActivityManagerService.this) {
4120                                    d.dismiss();
4121                                    mLaunchWarningShown = false;
4122                                }
4123                            }
4124                        }, 4000);
4125                    }
4126                }
4127            });
4128        }
4129    }
4130
4131    @Override
4132    public boolean clearApplicationUserData(final String packageName,
4133            final IPackageDataObserver observer, int userId) {
4134        enforceNotIsolatedCaller("clearApplicationUserData");
4135        int uid = Binder.getCallingUid();
4136        int pid = Binder.getCallingPid();
4137        userId = handleIncomingUser(pid, uid,
4138                userId, false, true, "clearApplicationUserData", null);
4139        long callingId = Binder.clearCallingIdentity();
4140        try {
4141            IPackageManager pm = AppGlobals.getPackageManager();
4142            int pkgUid = -1;
4143            synchronized(this) {
4144                try {
4145                    pkgUid = pm.getPackageUid(packageName, userId);
4146                } catch (RemoteException e) {
4147                }
4148                if (pkgUid == -1) {
4149                    Slog.w(TAG, "Invalid packageName: " + packageName);
4150                    if (observer != null) {
4151                        try {
4152                            observer.onRemoveCompleted(packageName, false);
4153                        } catch (RemoteException e) {
4154                            Slog.i(TAG, "Observer no longer exists.");
4155                        }
4156                    }
4157                    return false;
4158                }
4159                if (uid == pkgUid || checkComponentPermission(
4160                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4161                        pid, uid, -1, true)
4162                        == PackageManager.PERMISSION_GRANTED) {
4163                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4164                } else {
4165                    throw new SecurityException("PID " + pid + " does not have permission "
4166                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4167                                    + " of package " + packageName);
4168                }
4169            }
4170
4171            try {
4172                // Clear application user data
4173                pm.clearApplicationUserData(packageName, observer, userId);
4174
4175                // Remove all permissions granted from/to this package
4176                removeUriPermissionsForPackageLocked(packageName, userId, true);
4177
4178                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4179                        Uri.fromParts("package", packageName, null));
4180                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4181                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4182                        null, null, 0, null, null, null, false, false, userId);
4183            } catch (RemoteException e) {
4184            }
4185        } finally {
4186            Binder.restoreCallingIdentity(callingId);
4187        }
4188        return true;
4189    }
4190
4191    @Override
4192    public void killBackgroundProcesses(final String packageName, int userId) {
4193        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4194                != PackageManager.PERMISSION_GRANTED &&
4195                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4196                        != PackageManager.PERMISSION_GRANTED) {
4197            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4198                    + Binder.getCallingPid()
4199                    + ", uid=" + Binder.getCallingUid()
4200                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4201            Slog.w(TAG, msg);
4202            throw new SecurityException(msg);
4203        }
4204
4205        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4206                userId, true, true, "killBackgroundProcesses", null);
4207        long callingId = Binder.clearCallingIdentity();
4208        try {
4209            IPackageManager pm = AppGlobals.getPackageManager();
4210            synchronized(this) {
4211                int appId = -1;
4212                try {
4213                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4214                } catch (RemoteException e) {
4215                }
4216                if (appId == -1) {
4217                    Slog.w(TAG, "Invalid packageName: " + packageName);
4218                    return;
4219                }
4220                killPackageProcessesLocked(packageName, appId, userId,
4221                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4222            }
4223        } finally {
4224            Binder.restoreCallingIdentity(callingId);
4225        }
4226    }
4227
4228    @Override
4229    public void killAllBackgroundProcesses() {
4230        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4231                != PackageManager.PERMISSION_GRANTED) {
4232            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4233                    + Binder.getCallingPid()
4234                    + ", uid=" + Binder.getCallingUid()
4235                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4236            Slog.w(TAG, msg);
4237            throw new SecurityException(msg);
4238        }
4239
4240        long callingId = Binder.clearCallingIdentity();
4241        try {
4242            synchronized(this) {
4243                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4244                final int NP = mProcessNames.getMap().size();
4245                for (int ip=0; ip<NP; ip++) {
4246                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4247                    final int NA = apps.size();
4248                    for (int ia=0; ia<NA; ia++) {
4249                        ProcessRecord app = apps.valueAt(ia);
4250                        if (app.persistent) {
4251                            // we don't kill persistent processes
4252                            continue;
4253                        }
4254                        if (app.removed) {
4255                            procs.add(app);
4256                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4257                            app.removed = true;
4258                            procs.add(app);
4259                        }
4260                    }
4261                }
4262
4263                int N = procs.size();
4264                for (int i=0; i<N; i++) {
4265                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4266                }
4267                mAllowLowerMemLevel = true;
4268                updateOomAdjLocked();
4269                doLowMemReportIfNeededLocked(null);
4270            }
4271        } finally {
4272            Binder.restoreCallingIdentity(callingId);
4273        }
4274    }
4275
4276    @Override
4277    public void forceStopPackage(final String packageName, int userId) {
4278        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4279                != PackageManager.PERMISSION_GRANTED) {
4280            String msg = "Permission Denial: forceStopPackage() from pid="
4281                    + Binder.getCallingPid()
4282                    + ", uid=" + Binder.getCallingUid()
4283                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4284            Slog.w(TAG, msg);
4285            throw new SecurityException(msg);
4286        }
4287        final int callingPid = Binder.getCallingPid();
4288        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4289                userId, true, true, "forceStopPackage", null);
4290        long callingId = Binder.clearCallingIdentity();
4291        try {
4292            IPackageManager pm = AppGlobals.getPackageManager();
4293            synchronized(this) {
4294                int[] users = userId == UserHandle.USER_ALL
4295                        ? getUsersLocked() : new int[] { userId };
4296                for (int user : users) {
4297                    int pkgUid = -1;
4298                    try {
4299                        pkgUid = pm.getPackageUid(packageName, user);
4300                    } catch (RemoteException e) {
4301                    }
4302                    if (pkgUid == -1) {
4303                        Slog.w(TAG, "Invalid packageName: " + packageName);
4304                        continue;
4305                    }
4306                    try {
4307                        pm.setPackageStoppedState(packageName, true, user);
4308                    } catch (RemoteException e) {
4309                    } catch (IllegalArgumentException e) {
4310                        Slog.w(TAG, "Failed trying to unstop package "
4311                                + packageName + ": " + e);
4312                    }
4313                    if (isUserRunningLocked(user, false)) {
4314                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4315                    }
4316                }
4317            }
4318        } finally {
4319            Binder.restoreCallingIdentity(callingId);
4320        }
4321    }
4322
4323    /*
4324     * The pkg name and app id have to be specified.
4325     */
4326    @Override
4327    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4328        if (pkg == null) {
4329            return;
4330        }
4331        // Make sure the uid is valid.
4332        if (appid < 0) {
4333            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4334            return;
4335        }
4336        int callerUid = Binder.getCallingUid();
4337        // Only the system server can kill an application
4338        if (callerUid == Process.SYSTEM_UID) {
4339            // Post an aysnc message to kill the application
4340            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4341            msg.arg1 = appid;
4342            msg.arg2 = 0;
4343            Bundle bundle = new Bundle();
4344            bundle.putString("pkg", pkg);
4345            bundle.putString("reason", reason);
4346            msg.obj = bundle;
4347            mHandler.sendMessage(msg);
4348        } else {
4349            throw new SecurityException(callerUid + " cannot kill pkg: " +
4350                    pkg);
4351        }
4352    }
4353
4354    @Override
4355    public void closeSystemDialogs(String reason) {
4356        enforceNotIsolatedCaller("closeSystemDialogs");
4357
4358        final int pid = Binder.getCallingPid();
4359        final int uid = Binder.getCallingUid();
4360        final long origId = Binder.clearCallingIdentity();
4361        try {
4362            synchronized (this) {
4363                // Only allow this from foreground processes, so that background
4364                // applications can't abuse it to prevent system UI from being shown.
4365                if (uid >= Process.FIRST_APPLICATION_UID) {
4366                    ProcessRecord proc;
4367                    synchronized (mPidsSelfLocked) {
4368                        proc = mPidsSelfLocked.get(pid);
4369                    }
4370                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4371                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4372                                + " from background process " + proc);
4373                        return;
4374                    }
4375                }
4376                closeSystemDialogsLocked(reason);
4377            }
4378        } finally {
4379            Binder.restoreCallingIdentity(origId);
4380        }
4381    }
4382
4383    void closeSystemDialogsLocked(String reason) {
4384        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4385        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4386                | Intent.FLAG_RECEIVER_FOREGROUND);
4387        if (reason != null) {
4388            intent.putExtra("reason", reason);
4389        }
4390        mWindowManager.closeSystemDialogs(reason);
4391
4392        mStackSupervisor.closeSystemDialogsLocked();
4393
4394        broadcastIntentLocked(null, null, intent, null,
4395                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4396                Process.SYSTEM_UID, UserHandle.USER_ALL);
4397    }
4398
4399    @Override
4400    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4401        enforceNotIsolatedCaller("getProcessMemoryInfo");
4402        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4403        for (int i=pids.length-1; i>=0; i--) {
4404            ProcessRecord proc;
4405            int oomAdj;
4406            synchronized (this) {
4407                synchronized (mPidsSelfLocked) {
4408                    proc = mPidsSelfLocked.get(pids[i]);
4409                    oomAdj = proc != null ? proc.setAdj : 0;
4410                }
4411            }
4412            infos[i] = new Debug.MemoryInfo();
4413            Debug.getMemoryInfo(pids[i], infos[i]);
4414            if (proc != null) {
4415                synchronized (this) {
4416                    if (proc.thread != null && proc.setAdj == oomAdj) {
4417                        // Record this for posterity if the process has been stable.
4418                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4419                                infos[i].getTotalUss(), false, proc.pkgList);
4420                    }
4421                }
4422            }
4423        }
4424        return infos;
4425    }
4426
4427    @Override
4428    public long[] getProcessPss(int[] pids) {
4429        enforceNotIsolatedCaller("getProcessPss");
4430        long[] pss = new long[pids.length];
4431        for (int i=pids.length-1; i>=0; i--) {
4432            ProcessRecord proc;
4433            int oomAdj;
4434            synchronized (this) {
4435                synchronized (mPidsSelfLocked) {
4436                    proc = mPidsSelfLocked.get(pids[i]);
4437                    oomAdj = proc != null ? proc.setAdj : 0;
4438                }
4439            }
4440            long[] tmpUss = new long[1];
4441            pss[i] = Debug.getPss(pids[i], tmpUss);
4442            if (proc != null) {
4443                synchronized (this) {
4444                    if (proc.thread != null && proc.setAdj == oomAdj) {
4445                        // Record this for posterity if the process has been stable.
4446                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4447                    }
4448                }
4449            }
4450        }
4451        return pss;
4452    }
4453
4454    @Override
4455    public void killApplicationProcess(String processName, int uid) {
4456        if (processName == null) {
4457            return;
4458        }
4459
4460        int callerUid = Binder.getCallingUid();
4461        // Only the system server can kill an application
4462        if (callerUid == Process.SYSTEM_UID) {
4463            synchronized (this) {
4464                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4465                if (app != null && app.thread != null) {
4466                    try {
4467                        app.thread.scheduleSuicide();
4468                    } catch (RemoteException e) {
4469                        // If the other end already died, then our work here is done.
4470                    }
4471                } else {
4472                    Slog.w(TAG, "Process/uid not found attempting kill of "
4473                            + processName + " / " + uid);
4474                }
4475            }
4476        } else {
4477            throw new SecurityException(callerUid + " cannot kill app process: " +
4478                    processName);
4479        }
4480    }
4481
4482    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4483        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4484                false, true, false, false, UserHandle.getUserId(uid), reason);
4485        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4486                Uri.fromParts("package", packageName, null));
4487        if (!mProcessesReady) {
4488            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4489                    | Intent.FLAG_RECEIVER_FOREGROUND);
4490        }
4491        intent.putExtra(Intent.EXTRA_UID, uid);
4492        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4493        broadcastIntentLocked(null, null, intent,
4494                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4495                false, false,
4496                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4497    }
4498
4499    private void forceStopUserLocked(int userId, String reason) {
4500        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4501        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4502        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4503                | Intent.FLAG_RECEIVER_FOREGROUND);
4504        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4505        broadcastIntentLocked(null, null, intent,
4506                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4507                false, false,
4508                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4509    }
4510
4511    private final boolean killPackageProcessesLocked(String packageName, int appId,
4512            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4513            boolean doit, boolean evenPersistent, String reason) {
4514        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4515
4516        // Remove all processes this package may have touched: all with the
4517        // same UID (except for the system or root user), and all whose name
4518        // matches the package name.
4519        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4520        final int NP = mProcessNames.getMap().size();
4521        for (int ip=0; ip<NP; ip++) {
4522            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4523            final int NA = apps.size();
4524            for (int ia=0; ia<NA; ia++) {
4525                ProcessRecord app = apps.valueAt(ia);
4526                if (app.persistent && !evenPersistent) {
4527                    // we don't kill persistent processes
4528                    continue;
4529                }
4530                if (app.removed) {
4531                    if (doit) {
4532                        procs.add(app);
4533                    }
4534                    continue;
4535                }
4536
4537                // Skip process if it doesn't meet our oom adj requirement.
4538                if (app.setAdj < minOomAdj) {
4539                    continue;
4540                }
4541
4542                // If no package is specified, we call all processes under the
4543                // give user id.
4544                if (packageName == null) {
4545                    if (app.userId != userId) {
4546                        continue;
4547                    }
4548                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4549                        continue;
4550                    }
4551                // Package has been specified, we want to hit all processes
4552                // that match it.  We need to qualify this by the processes
4553                // that are running under the specified app and user ID.
4554                } else {
4555                    if (UserHandle.getAppId(app.uid) != appId) {
4556                        continue;
4557                    }
4558                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4559                        continue;
4560                    }
4561                    if (!app.pkgList.containsKey(packageName)) {
4562                        continue;
4563                    }
4564                }
4565
4566                // Process has passed all conditions, kill it!
4567                if (!doit) {
4568                    return true;
4569                }
4570                app.removed = true;
4571                procs.add(app);
4572            }
4573        }
4574
4575        int N = procs.size();
4576        for (int i=0; i<N; i++) {
4577            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4578        }
4579        updateOomAdjLocked();
4580        return N > 0;
4581    }
4582
4583    private final boolean forceStopPackageLocked(String name, int appId,
4584            boolean callerWillRestart, boolean purgeCache, boolean doit,
4585            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4586        int i;
4587        int N;
4588
4589        if (userId == UserHandle.USER_ALL && name == null) {
4590            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4591        }
4592
4593        if (appId < 0 && name != null) {
4594            try {
4595                appId = UserHandle.getAppId(
4596                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4597            } catch (RemoteException e) {
4598            }
4599        }
4600
4601        if (doit) {
4602            if (name != null) {
4603                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4604                        + " user=" + userId + ": " + reason);
4605            } else {
4606                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4607            }
4608
4609            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4610            for (int ip=pmap.size()-1; ip>=0; ip--) {
4611                SparseArray<Long> ba = pmap.valueAt(ip);
4612                for (i=ba.size()-1; i>=0; i--) {
4613                    boolean remove = false;
4614                    final int entUid = ba.keyAt(i);
4615                    if (name != null) {
4616                        if (userId == UserHandle.USER_ALL) {
4617                            if (UserHandle.getAppId(entUid) == appId) {
4618                                remove = true;
4619                            }
4620                        } else {
4621                            if (entUid == UserHandle.getUid(userId, appId)) {
4622                                remove = true;
4623                            }
4624                        }
4625                    } else if (UserHandle.getUserId(entUid) == userId) {
4626                        remove = true;
4627                    }
4628                    if (remove) {
4629                        ba.removeAt(i);
4630                    }
4631                }
4632                if (ba.size() == 0) {
4633                    pmap.removeAt(ip);
4634                }
4635            }
4636        }
4637
4638        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4639                -100, callerWillRestart, true, doit, evenPersistent,
4640                name == null ? ("stop user " + userId) : ("stop " + name));
4641
4642        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4643            if (!doit) {
4644                return true;
4645            }
4646            didSomething = true;
4647        }
4648
4649        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4650            if (!doit) {
4651                return true;
4652            }
4653            didSomething = true;
4654        }
4655
4656        if (name == null) {
4657            // Remove all sticky broadcasts from this user.
4658            mStickyBroadcasts.remove(userId);
4659        }
4660
4661        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
4662        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
4663                userId, providers)) {
4664            if (!doit) {
4665                return true;
4666            }
4667            didSomething = true;
4668        }
4669        N = providers.size();
4670        for (i=0; i<N; i++) {
4671            removeDyingProviderLocked(null, providers.get(i), true);
4672        }
4673
4674        // Remove transient permissions granted from/to this package/user
4675        removeUriPermissionsForPackageLocked(name, userId, false);
4676
4677        if (name == null || uninstalling) {
4678            // Remove pending intents.  For now we only do this when force
4679            // stopping users, because we have some problems when doing this
4680            // for packages -- app widgets are not currently cleaned up for
4681            // such packages, so they can be left with bad pending intents.
4682            if (mIntentSenderRecords.size() > 0) {
4683                Iterator<WeakReference<PendingIntentRecord>> it
4684                        = mIntentSenderRecords.values().iterator();
4685                while (it.hasNext()) {
4686                    WeakReference<PendingIntentRecord> wpir = it.next();
4687                    if (wpir == null) {
4688                        it.remove();
4689                        continue;
4690                    }
4691                    PendingIntentRecord pir = wpir.get();
4692                    if (pir == null) {
4693                        it.remove();
4694                        continue;
4695                    }
4696                    if (name == null) {
4697                        // Stopping user, remove all objects for the user.
4698                        if (pir.key.userId != userId) {
4699                            // Not the same user, skip it.
4700                            continue;
4701                        }
4702                    } else {
4703                        if (UserHandle.getAppId(pir.uid) != appId) {
4704                            // Different app id, skip it.
4705                            continue;
4706                        }
4707                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4708                            // Different user, skip it.
4709                            continue;
4710                        }
4711                        if (!pir.key.packageName.equals(name)) {
4712                            // Different package, skip it.
4713                            continue;
4714                        }
4715                    }
4716                    if (!doit) {
4717                        return true;
4718                    }
4719                    didSomething = true;
4720                    it.remove();
4721                    pir.canceled = true;
4722                    if (pir.key.activity != null) {
4723                        pir.key.activity.pendingResults.remove(pir.ref);
4724                    }
4725                }
4726            }
4727        }
4728
4729        if (doit) {
4730            if (purgeCache && name != null) {
4731                AttributeCache ac = AttributeCache.instance();
4732                if (ac != null) {
4733                    ac.removePackage(name);
4734                }
4735            }
4736            if (mBooted) {
4737                mStackSupervisor.resumeTopActivitiesLocked();
4738                mStackSupervisor.scheduleIdleLocked();
4739            }
4740        }
4741
4742        return didSomething;
4743    }
4744
4745    private final boolean removeProcessLocked(ProcessRecord app,
4746            boolean callerWillRestart, boolean allowRestart, String reason) {
4747        final String name = app.processName;
4748        final int uid = app.uid;
4749        if (DEBUG_PROCESSES) Slog.d(
4750            TAG, "Force removing proc " + app.toShortString() + " (" + name
4751            + "/" + uid + ")");
4752
4753        mProcessNames.remove(name, uid);
4754        mIsolatedProcesses.remove(app.uid);
4755        if (mHeavyWeightProcess == app) {
4756            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4757                    mHeavyWeightProcess.userId, 0));
4758            mHeavyWeightProcess = null;
4759        }
4760        boolean needRestart = false;
4761        if (app.pid > 0 && app.pid != MY_PID) {
4762            int pid = app.pid;
4763            synchronized (mPidsSelfLocked) {
4764                mPidsSelfLocked.remove(pid);
4765                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4766            }
4767            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4768                    app.processName, app.info.uid);
4769            if (app.isolated) {
4770                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4771            }
4772            killUnneededProcessLocked(app, reason);
4773            handleAppDiedLocked(app, true, allowRestart);
4774            removeLruProcessLocked(app);
4775
4776            if (app.persistent && !app.isolated) {
4777                if (!callerWillRestart) {
4778                    addAppLocked(app.info, false);
4779                } else {
4780                    needRestart = true;
4781                }
4782            }
4783        } else {
4784            mRemovedProcesses.add(app);
4785        }
4786
4787        return needRestart;
4788    }
4789
4790    private final void processStartTimedOutLocked(ProcessRecord app) {
4791        final int pid = app.pid;
4792        boolean gone = false;
4793        synchronized (mPidsSelfLocked) {
4794            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4795            if (knownApp != null && knownApp.thread == null) {
4796                mPidsSelfLocked.remove(pid);
4797                gone = true;
4798            }
4799        }
4800
4801        if (gone) {
4802            Slog.w(TAG, "Process " + app + " failed to attach");
4803            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4804                    pid, app.uid, app.processName);
4805            mProcessNames.remove(app.processName, app.uid);
4806            mIsolatedProcesses.remove(app.uid);
4807            if (mHeavyWeightProcess == app) {
4808                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4809                        mHeavyWeightProcess.userId, 0));
4810                mHeavyWeightProcess = null;
4811            }
4812            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
4813                    app.processName, app.info.uid);
4814            if (app.isolated) {
4815                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
4816            }
4817            // Take care of any launching providers waiting for this process.
4818            checkAppInLaunchingProvidersLocked(app, true);
4819            // Take care of any services that are waiting for the process.
4820            mServices.processStartTimedOutLocked(app);
4821            killUnneededProcessLocked(app, "start timeout");
4822            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4823                Slog.w(TAG, "Unattached app died before backup, skipping");
4824                try {
4825                    IBackupManager bm = IBackupManager.Stub.asInterface(
4826                            ServiceManager.getService(Context.BACKUP_SERVICE));
4827                    bm.agentDisconnected(app.info.packageName);
4828                } catch (RemoteException e) {
4829                    // Can't happen; the backup manager is local
4830                }
4831            }
4832            if (isPendingBroadcastProcessLocked(pid)) {
4833                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4834                skipPendingBroadcastLocked(pid);
4835            }
4836        } else {
4837            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4838        }
4839    }
4840
4841    private final boolean attachApplicationLocked(IApplicationThread thread,
4842            int pid) {
4843
4844        // Find the application record that is being attached...  either via
4845        // the pid if we are running in multiple processes, or just pull the
4846        // next app record if we are emulating process with anonymous threads.
4847        ProcessRecord app;
4848        if (pid != MY_PID && pid >= 0) {
4849            synchronized (mPidsSelfLocked) {
4850                app = mPidsSelfLocked.get(pid);
4851            }
4852        } else {
4853            app = null;
4854        }
4855
4856        if (app == null) {
4857            Slog.w(TAG, "No pending application record for pid " + pid
4858                    + " (IApplicationThread " + thread + "); dropping process");
4859            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4860            if (pid > 0 && pid != MY_PID) {
4861                Process.killProcessQuiet(pid);
4862            } else {
4863                try {
4864                    thread.scheduleExit();
4865                } catch (Exception e) {
4866                    // Ignore exceptions.
4867                }
4868            }
4869            return false;
4870        }
4871
4872        // If this application record is still attached to a previous
4873        // process, clean it up now.
4874        if (app.thread != null) {
4875            handleAppDiedLocked(app, true, true);
4876        }
4877
4878        // Tell the process all about itself.
4879
4880        if (localLOGV) Slog.v(
4881                TAG, "Binding process pid " + pid + " to record " + app);
4882
4883        final String processName = app.processName;
4884        try {
4885            AppDeathRecipient adr = new AppDeathRecipient(
4886                    app, pid, thread);
4887            thread.asBinder().linkToDeath(adr, 0);
4888            app.deathRecipient = adr;
4889        } catch (RemoteException e) {
4890            app.resetPackageList(mProcessStats);
4891            startProcessLocked(app, "link fail", processName);
4892            return false;
4893        }
4894
4895        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4896
4897        app.makeActive(thread, mProcessStats);
4898        app.curAdj = app.setAdj = -100;
4899        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
4900        app.forcingToForeground = null;
4901        updateProcessForegroundLocked(app, false, false);
4902        app.hasShownUi = false;
4903        app.debugging = false;
4904        app.cached = false;
4905
4906        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4907
4908        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4909        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4910
4911        if (!normalMode) {
4912            Slog.i(TAG, "Launching preboot mode app: " + app);
4913        }
4914
4915        if (localLOGV) Slog.v(
4916            TAG, "New app record " + app
4917            + " thread=" + thread.asBinder() + " pid=" + pid);
4918        try {
4919            int testMode = IApplicationThread.DEBUG_OFF;
4920            if (mDebugApp != null && mDebugApp.equals(processName)) {
4921                testMode = mWaitForDebugger
4922                    ? IApplicationThread.DEBUG_WAIT
4923                    : IApplicationThread.DEBUG_ON;
4924                app.debugging = true;
4925                if (mDebugTransient) {
4926                    mDebugApp = mOrigDebugApp;
4927                    mWaitForDebugger = mOrigWaitForDebugger;
4928                }
4929            }
4930            String profileFile = app.instrumentationProfileFile;
4931            ParcelFileDescriptor profileFd = null;
4932            boolean profileAutoStop = false;
4933            if (mProfileApp != null && mProfileApp.equals(processName)) {
4934                mProfileProc = app;
4935                profileFile = mProfileFile;
4936                profileFd = mProfileFd;
4937                profileAutoStop = mAutoStopProfiler;
4938            }
4939            boolean enableOpenGlTrace = false;
4940            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4941                enableOpenGlTrace = true;
4942                mOpenGlTraceApp = null;
4943            }
4944
4945            // If the app is being launched for restore or full backup, set it up specially
4946            boolean isRestrictedBackupMode = false;
4947            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4948                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4949                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4950                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4951            }
4952
4953            ensurePackageDexOpt(app.instrumentationInfo != null
4954                    ? app.instrumentationInfo.packageName
4955                    : app.info.packageName);
4956            if (app.instrumentationClass != null) {
4957                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4958            }
4959            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4960                    + processName + " with config " + mConfiguration);
4961            ApplicationInfo appInfo = app.instrumentationInfo != null
4962                    ? app.instrumentationInfo : app.info;
4963            app.compat = compatibilityInfoForPackageLocked(appInfo);
4964            if (profileFd != null) {
4965                profileFd = profileFd.dup();
4966            }
4967            thread.bindApplication(processName, appInfo, providers,
4968                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4969                    app.instrumentationArguments, app.instrumentationWatcher,
4970                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
4971                    isRestrictedBackupMode || !normalMode, app.persistent,
4972                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4973                    mCoreSettingsObserver.getCoreSettingsLocked());
4974            updateLruProcessLocked(app, false, null);
4975            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4976        } catch (Exception e) {
4977            // todo: Yikes!  What should we do?  For now we will try to
4978            // start another process, but that could easily get us in
4979            // an infinite loop of restarting processes...
4980            Slog.w(TAG, "Exception thrown during bind!", e);
4981
4982            app.resetPackageList(mProcessStats);
4983            app.unlinkDeathRecipient();
4984            startProcessLocked(app, "bind fail", processName);
4985            return false;
4986        }
4987
4988        // Remove this record from the list of starting applications.
4989        mPersistentStartingProcesses.remove(app);
4990        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4991                "Attach application locked removing on hold: " + app);
4992        mProcessesOnHold.remove(app);
4993
4994        boolean badApp = false;
4995        boolean didSomething = false;
4996
4997        // See if the top visible activity is waiting to run in this process...
4998        if (normalMode) {
4999            try {
5000                if (mStackSupervisor.attachApplicationLocked(app)) {
5001                    didSomething = true;
5002                }
5003            } catch (Exception e) {
5004                badApp = true;
5005            }
5006        }
5007
5008        // Find any services that should be running in this process...
5009        if (!badApp) {
5010            try {
5011                didSomething |= mServices.attachApplicationLocked(app, processName);
5012            } catch (Exception e) {
5013                badApp = true;
5014            }
5015        }
5016
5017        // Check if a next-broadcast receiver is in this process...
5018        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5019            try {
5020                didSomething |= sendPendingBroadcastsLocked(app);
5021            } catch (Exception e) {
5022                // If the app died trying to launch the receiver we declare it 'bad'
5023                badApp = true;
5024            }
5025        }
5026
5027        // Check whether the next backup agent is in this process...
5028        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5029            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5030            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5031            try {
5032                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5033                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5034                        mBackupTarget.backupMode);
5035            } catch (Exception e) {
5036                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5037                e.printStackTrace();
5038            }
5039        }
5040
5041        if (badApp) {
5042            // todo: Also need to kill application to deal with all
5043            // kinds of exceptions.
5044            handleAppDiedLocked(app, false, true);
5045            return false;
5046        }
5047
5048        if (!didSomething) {
5049            updateOomAdjLocked();
5050        }
5051
5052        return true;
5053    }
5054
5055    @Override
5056    public final void attachApplication(IApplicationThread thread) {
5057        synchronized (this) {
5058            int callingPid = Binder.getCallingPid();
5059            final long origId = Binder.clearCallingIdentity();
5060            attachApplicationLocked(thread, callingPid);
5061            Binder.restoreCallingIdentity(origId);
5062        }
5063    }
5064
5065    @Override
5066    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5067        final long origId = Binder.clearCallingIdentity();
5068        synchronized (this) {
5069            ActivityStack stack = ActivityRecord.getStackLocked(token);
5070            if (stack != null) {
5071                ActivityRecord r =
5072                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5073                if (stopProfiling) {
5074                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5075                        try {
5076                            mProfileFd.close();
5077                        } catch (IOException e) {
5078                        }
5079                        clearProfilerLocked();
5080                    }
5081                }
5082            }
5083        }
5084        Binder.restoreCallingIdentity(origId);
5085    }
5086
5087    void enableScreenAfterBoot() {
5088        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5089                SystemClock.uptimeMillis());
5090        mWindowManager.enableScreenAfterBoot();
5091
5092        synchronized (this) {
5093            updateEventDispatchingLocked();
5094        }
5095    }
5096
5097    @Override
5098    public void showBootMessage(final CharSequence msg, final boolean always) {
5099        enforceNotIsolatedCaller("showBootMessage");
5100        mWindowManager.showBootMessage(msg, always);
5101    }
5102
5103    @Override
5104    public void dismissKeyguardOnNextActivity() {
5105        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5106        final long token = Binder.clearCallingIdentity();
5107        try {
5108            synchronized (this) {
5109                if (DEBUG_LOCKSCREEN) logLockScreen("");
5110                if (mLockScreenShown) {
5111                    mLockScreenShown = false;
5112                    comeOutOfSleepIfNeededLocked();
5113                }
5114                mStackSupervisor.setDismissKeyguard(true);
5115            }
5116        } finally {
5117            Binder.restoreCallingIdentity(token);
5118        }
5119    }
5120
5121    final void finishBooting() {
5122        IntentFilter pkgFilter = new IntentFilter();
5123        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
5124        pkgFilter.addDataScheme("package");
5125        mContext.registerReceiver(new BroadcastReceiver() {
5126            @Override
5127            public void onReceive(Context context, Intent intent) {
5128                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
5129                if (pkgs != null) {
5130                    for (String pkg : pkgs) {
5131                        synchronized (ActivityManagerService.this) {
5132                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
5133                                    "finished booting")) {
5134                                setResultCode(Activity.RESULT_OK);
5135                                return;
5136                            }
5137                        }
5138                    }
5139                }
5140            }
5141        }, pkgFilter);
5142
5143        synchronized (this) {
5144            // Ensure that any processes we had put on hold are now started
5145            // up.
5146            final int NP = mProcessesOnHold.size();
5147            if (NP > 0) {
5148                ArrayList<ProcessRecord> procs =
5149                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5150                for (int ip=0; ip<NP; ip++) {
5151                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5152                            + procs.get(ip));
5153                    startProcessLocked(procs.get(ip), "on-hold", null);
5154                }
5155            }
5156
5157            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5158                // Start looking for apps that are abusing wake locks.
5159                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5160                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5161                // Tell anyone interested that we are done booting!
5162                SystemProperties.set("sys.boot_completed", "1");
5163                SystemProperties.set("dev.bootcomplete", "1");
5164                for (int i=0; i<mStartedUsers.size(); i++) {
5165                    UserStartedState uss = mStartedUsers.valueAt(i);
5166                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5167                        uss.mState = UserStartedState.STATE_RUNNING;
5168                        final int userId = mStartedUsers.keyAt(i);
5169                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5170                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5171                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5172                        broadcastIntentLocked(null, null, intent, null,
5173                                new IIntentReceiver.Stub() {
5174                                    @Override
5175                                    public void performReceive(Intent intent, int resultCode,
5176                                            String data, Bundle extras, boolean ordered,
5177                                            boolean sticky, int sendingUser) {
5178                                        synchronized (ActivityManagerService.this) {
5179                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5180                                                    true, false);
5181                                        }
5182                                    }
5183                                },
5184                                0, null, null,
5185                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5186                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5187                                userId);
5188                    }
5189                }
5190                scheduleStartRelatedUsersLocked();
5191            }
5192        }
5193    }
5194
5195    final void ensureBootCompleted() {
5196        boolean booting;
5197        boolean enableScreen;
5198        synchronized (this) {
5199            booting = mBooting;
5200            mBooting = false;
5201            enableScreen = !mBooted;
5202            mBooted = true;
5203        }
5204
5205        if (booting) {
5206            finishBooting();
5207        }
5208
5209        if (enableScreen) {
5210            enableScreenAfterBoot();
5211        }
5212    }
5213
5214    @Override
5215    public final void activityResumed(IBinder token) {
5216        final long origId = Binder.clearCallingIdentity();
5217        synchronized(this) {
5218            ActivityStack stack = ActivityRecord.getStackLocked(token);
5219            if (stack != null) {
5220                ActivityRecord.activityResumedLocked(token);
5221            }
5222        }
5223        Binder.restoreCallingIdentity(origId);
5224    }
5225
5226    @Override
5227    public final void activityPaused(IBinder token) {
5228        final long origId = Binder.clearCallingIdentity();
5229        synchronized(this) {
5230            ActivityStack stack = ActivityRecord.getStackLocked(token);
5231            if (stack != null) {
5232                stack.activityPausedLocked(token, false);
5233            }
5234        }
5235        Binder.restoreCallingIdentity(origId);
5236    }
5237
5238    @Override
5239    public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
5240            CharSequence description) {
5241        if (localLOGV) Slog.v(
5242            TAG, "Activity stopped: token=" + token);
5243
5244        // Refuse possible leaked file descriptors
5245        if (icicle != null && icicle.hasFileDescriptors()) {
5246            throw new IllegalArgumentException("File descriptors passed in Bundle");
5247        }
5248
5249        ActivityRecord r = null;
5250
5251        final long origId = Binder.clearCallingIdentity();
5252
5253        synchronized (this) {
5254            r = ActivityRecord.isInStackLocked(token);
5255            if (r != null) {
5256                r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
5257            }
5258        }
5259
5260        if (r != null) {
5261            sendPendingThumbnail(r, null, null, null, false);
5262        }
5263
5264        trimApplications();
5265
5266        Binder.restoreCallingIdentity(origId);
5267    }
5268
5269    @Override
5270    public final void activityDestroyed(IBinder token) {
5271        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5272        synchronized (this) {
5273            ActivityStack stack = ActivityRecord.getStackLocked(token);
5274            if (stack != null) {
5275                stack.activityDestroyedLocked(token);
5276            }
5277        }
5278    }
5279
5280    @Override
5281    public String getCallingPackage(IBinder token) {
5282        synchronized (this) {
5283            ActivityRecord r = getCallingRecordLocked(token);
5284            return r != null ? r.info.packageName : null;
5285        }
5286    }
5287
5288    @Override
5289    public ComponentName getCallingActivity(IBinder token) {
5290        synchronized (this) {
5291            ActivityRecord r = getCallingRecordLocked(token);
5292            return r != null ? r.intent.getComponent() : null;
5293        }
5294    }
5295
5296    private ActivityRecord getCallingRecordLocked(IBinder token) {
5297        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5298        if (r == null) {
5299            return null;
5300        }
5301        return r.resultTo;
5302    }
5303
5304    @Override
5305    public ComponentName getActivityClassForToken(IBinder token) {
5306        synchronized(this) {
5307            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5308            if (r == null) {
5309                return null;
5310            }
5311            return r.intent.getComponent();
5312        }
5313    }
5314
5315    @Override
5316    public String getPackageForToken(IBinder token) {
5317        synchronized(this) {
5318            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5319            if (r == null) {
5320                return null;
5321            }
5322            return r.packageName;
5323        }
5324    }
5325
5326    @Override
5327    public IIntentSender getIntentSender(int type,
5328            String packageName, IBinder token, String resultWho,
5329            int requestCode, Intent[] intents, String[] resolvedTypes,
5330            int flags, Bundle options, int userId) {
5331        enforceNotIsolatedCaller("getIntentSender");
5332        // Refuse possible leaked file descriptors
5333        if (intents != null) {
5334            if (intents.length < 1) {
5335                throw new IllegalArgumentException("Intents array length must be >= 1");
5336            }
5337            for (int i=0; i<intents.length; i++) {
5338                Intent intent = intents[i];
5339                if (intent != null) {
5340                    if (intent.hasFileDescriptors()) {
5341                        throw new IllegalArgumentException("File descriptors passed in Intent");
5342                    }
5343                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5344                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5345                        throw new IllegalArgumentException(
5346                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5347                    }
5348                    intents[i] = new Intent(intent);
5349                }
5350            }
5351            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5352                throw new IllegalArgumentException(
5353                        "Intent array length does not match resolvedTypes length");
5354            }
5355        }
5356        if (options != null) {
5357            if (options.hasFileDescriptors()) {
5358                throw new IllegalArgumentException("File descriptors passed in options");
5359            }
5360        }
5361
5362        synchronized(this) {
5363            int callingUid = Binder.getCallingUid();
5364            int origUserId = userId;
5365            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5366                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5367                    "getIntentSender", null);
5368            if (origUserId == UserHandle.USER_CURRENT) {
5369                // We don't want to evaluate this until the pending intent is
5370                // actually executed.  However, we do want to always do the
5371                // security checking for it above.
5372                userId = UserHandle.USER_CURRENT;
5373            }
5374            try {
5375                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5376                    int uid = AppGlobals.getPackageManager()
5377                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5378                    if (!UserHandle.isSameApp(callingUid, uid)) {
5379                        String msg = "Permission Denial: getIntentSender() from pid="
5380                            + Binder.getCallingPid()
5381                            + ", uid=" + Binder.getCallingUid()
5382                            + ", (need uid=" + uid + ")"
5383                            + " is not allowed to send as package " + packageName;
5384                        Slog.w(TAG, msg);
5385                        throw new SecurityException(msg);
5386                    }
5387                }
5388
5389                return getIntentSenderLocked(type, packageName, callingUid, userId,
5390                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5391
5392            } catch (RemoteException e) {
5393                throw new SecurityException(e);
5394            }
5395        }
5396    }
5397
5398    IIntentSender getIntentSenderLocked(int type, String packageName,
5399            int callingUid, int userId, IBinder token, String resultWho,
5400            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5401            Bundle options) {
5402        if (DEBUG_MU)
5403            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5404        ActivityRecord activity = null;
5405        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5406            activity = ActivityRecord.isInStackLocked(token);
5407            if (activity == null) {
5408                return null;
5409            }
5410            if (activity.finishing) {
5411                return null;
5412            }
5413        }
5414
5415        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5416        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5417        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5418        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5419                |PendingIntent.FLAG_UPDATE_CURRENT);
5420
5421        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5422                type, packageName, activity, resultWho,
5423                requestCode, intents, resolvedTypes, flags, options, userId);
5424        WeakReference<PendingIntentRecord> ref;
5425        ref = mIntentSenderRecords.get(key);
5426        PendingIntentRecord rec = ref != null ? ref.get() : null;
5427        if (rec != null) {
5428            if (!cancelCurrent) {
5429                if (updateCurrent) {
5430                    if (rec.key.requestIntent != null) {
5431                        rec.key.requestIntent.replaceExtras(intents != null ?
5432                                intents[intents.length - 1] : null);
5433                    }
5434                    if (intents != null) {
5435                        intents[intents.length-1] = rec.key.requestIntent;
5436                        rec.key.allIntents = intents;
5437                        rec.key.allResolvedTypes = resolvedTypes;
5438                    } else {
5439                        rec.key.allIntents = null;
5440                        rec.key.allResolvedTypes = null;
5441                    }
5442                }
5443                return rec;
5444            }
5445            rec.canceled = true;
5446            mIntentSenderRecords.remove(key);
5447        }
5448        if (noCreate) {
5449            return rec;
5450        }
5451        rec = new PendingIntentRecord(this, key, callingUid);
5452        mIntentSenderRecords.put(key, rec.ref);
5453        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5454            if (activity.pendingResults == null) {
5455                activity.pendingResults
5456                        = new HashSet<WeakReference<PendingIntentRecord>>();
5457            }
5458            activity.pendingResults.add(rec.ref);
5459        }
5460        return rec;
5461    }
5462
5463    @Override
5464    public void cancelIntentSender(IIntentSender sender) {
5465        if (!(sender instanceof PendingIntentRecord)) {
5466            return;
5467        }
5468        synchronized(this) {
5469            PendingIntentRecord rec = (PendingIntentRecord)sender;
5470            try {
5471                int uid = AppGlobals.getPackageManager()
5472                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5473                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5474                    String msg = "Permission Denial: cancelIntentSender() from pid="
5475                        + Binder.getCallingPid()
5476                        + ", uid=" + Binder.getCallingUid()
5477                        + " is not allowed to cancel packges "
5478                        + rec.key.packageName;
5479                    Slog.w(TAG, msg);
5480                    throw new SecurityException(msg);
5481                }
5482            } catch (RemoteException e) {
5483                throw new SecurityException(e);
5484            }
5485            cancelIntentSenderLocked(rec, true);
5486        }
5487    }
5488
5489    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5490        rec.canceled = true;
5491        mIntentSenderRecords.remove(rec.key);
5492        if (cleanActivity && rec.key.activity != null) {
5493            rec.key.activity.pendingResults.remove(rec.ref);
5494        }
5495    }
5496
5497    @Override
5498    public String getPackageForIntentSender(IIntentSender pendingResult) {
5499        if (!(pendingResult instanceof PendingIntentRecord)) {
5500            return null;
5501        }
5502        try {
5503            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5504            return res.key.packageName;
5505        } catch (ClassCastException e) {
5506        }
5507        return null;
5508    }
5509
5510    @Override
5511    public int getUidForIntentSender(IIntentSender sender) {
5512        if (sender instanceof PendingIntentRecord) {
5513            try {
5514                PendingIntentRecord res = (PendingIntentRecord)sender;
5515                return res.uid;
5516            } catch (ClassCastException e) {
5517            }
5518        }
5519        return -1;
5520    }
5521
5522    @Override
5523    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5524        if (!(pendingResult instanceof PendingIntentRecord)) {
5525            return false;
5526        }
5527        try {
5528            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5529            if (res.key.allIntents == null) {
5530                return false;
5531            }
5532            for (int i=0; i<res.key.allIntents.length; i++) {
5533                Intent intent = res.key.allIntents[i];
5534                if (intent.getPackage() != null && intent.getComponent() != null) {
5535                    return false;
5536                }
5537            }
5538            return true;
5539        } catch (ClassCastException e) {
5540        }
5541        return false;
5542    }
5543
5544    @Override
5545    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5546        if (!(pendingResult instanceof PendingIntentRecord)) {
5547            return false;
5548        }
5549        try {
5550            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5551            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5552                return true;
5553            }
5554            return false;
5555        } catch (ClassCastException e) {
5556        }
5557        return false;
5558    }
5559
5560    @Override
5561    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5562        if (!(pendingResult instanceof PendingIntentRecord)) {
5563            return null;
5564        }
5565        try {
5566            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5567            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5568        } catch (ClassCastException e) {
5569        }
5570        return null;
5571    }
5572
5573    @Override
5574    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5575        if (!(pendingResult instanceof PendingIntentRecord)) {
5576            return null;
5577        }
5578        try {
5579            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5580            Intent intent = res.key.requestIntent;
5581            if (intent != null) {
5582                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5583                        || res.lastTagPrefix.equals(prefix))) {
5584                    return res.lastTag;
5585                }
5586                res.lastTagPrefix = prefix;
5587                StringBuilder sb = new StringBuilder(128);
5588                if (prefix != null) {
5589                    sb.append(prefix);
5590                }
5591                if (intent.getAction() != null) {
5592                    sb.append(intent.getAction());
5593                } else if (intent.getComponent() != null) {
5594                    intent.getComponent().appendShortString(sb);
5595                } else {
5596                    sb.append("?");
5597                }
5598                return res.lastTag = sb.toString();
5599            }
5600        } catch (ClassCastException e) {
5601        }
5602        return null;
5603    }
5604
5605    @Override
5606    public void setProcessLimit(int max) {
5607        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5608                "setProcessLimit()");
5609        synchronized (this) {
5610            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5611            mProcessLimitOverride = max;
5612        }
5613        trimApplications();
5614    }
5615
5616    @Override
5617    public int getProcessLimit() {
5618        synchronized (this) {
5619            return mProcessLimitOverride;
5620        }
5621    }
5622
5623    void foregroundTokenDied(ForegroundToken token) {
5624        synchronized (ActivityManagerService.this) {
5625            synchronized (mPidsSelfLocked) {
5626                ForegroundToken cur
5627                    = mForegroundProcesses.get(token.pid);
5628                if (cur != token) {
5629                    return;
5630                }
5631                mForegroundProcesses.remove(token.pid);
5632                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5633                if (pr == null) {
5634                    return;
5635                }
5636                pr.forcingToForeground = null;
5637                updateProcessForegroundLocked(pr, false, false);
5638            }
5639            updateOomAdjLocked();
5640        }
5641    }
5642
5643    @Override
5644    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5645        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5646                "setProcessForeground()");
5647        synchronized(this) {
5648            boolean changed = false;
5649
5650            synchronized (mPidsSelfLocked) {
5651                ProcessRecord pr = mPidsSelfLocked.get(pid);
5652                if (pr == null && isForeground) {
5653                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5654                    return;
5655                }
5656                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5657                if (oldToken != null) {
5658                    oldToken.token.unlinkToDeath(oldToken, 0);
5659                    mForegroundProcesses.remove(pid);
5660                    if (pr != null) {
5661                        pr.forcingToForeground = null;
5662                    }
5663                    changed = true;
5664                }
5665                if (isForeground && token != null) {
5666                    ForegroundToken newToken = new ForegroundToken() {
5667                        @Override
5668                        public void binderDied() {
5669                            foregroundTokenDied(this);
5670                        }
5671                    };
5672                    newToken.pid = pid;
5673                    newToken.token = token;
5674                    try {
5675                        token.linkToDeath(newToken, 0);
5676                        mForegroundProcesses.put(pid, newToken);
5677                        pr.forcingToForeground = token;
5678                        changed = true;
5679                    } catch (RemoteException e) {
5680                        // If the process died while doing this, we will later
5681                        // do the cleanup with the process death link.
5682                    }
5683                }
5684            }
5685
5686            if (changed) {
5687                updateOomAdjLocked();
5688            }
5689        }
5690    }
5691
5692    // =========================================================
5693    // PERMISSIONS
5694    // =========================================================
5695
5696    static class PermissionController extends IPermissionController.Stub {
5697        ActivityManagerService mActivityManagerService;
5698        PermissionController(ActivityManagerService activityManagerService) {
5699            mActivityManagerService = activityManagerService;
5700        }
5701
5702        @Override
5703        public boolean checkPermission(String permission, int pid, int uid) {
5704            return mActivityManagerService.checkPermission(permission, pid,
5705                    uid) == PackageManager.PERMISSION_GRANTED;
5706        }
5707    }
5708
5709    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
5710        @Override
5711        public int checkComponentPermission(String permission, int pid, int uid,
5712                int owningUid, boolean exported) {
5713            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
5714                    owningUid, exported);
5715        }
5716
5717        @Override
5718        public Object getAMSLock() {
5719            return ActivityManagerService.this;
5720        }
5721    }
5722
5723    /**
5724     * This can be called with or without the global lock held.
5725     */
5726    int checkComponentPermission(String permission, int pid, int uid,
5727            int owningUid, boolean exported) {
5728        // We might be performing an operation on behalf of an indirect binder
5729        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
5730        // client identity accordingly before proceeding.
5731        Identity tlsIdentity = sCallerIdentity.get();
5732        if (tlsIdentity != null) {
5733            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
5734                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
5735            uid = tlsIdentity.uid;
5736            pid = tlsIdentity.pid;
5737        }
5738
5739        if (pid == MY_PID) {
5740            return PackageManager.PERMISSION_GRANTED;
5741        }
5742
5743        return ActivityManager.checkComponentPermission(permission, uid,
5744                owningUid, exported);
5745    }
5746
5747    /**
5748     * As the only public entry point for permissions checking, this method
5749     * can enforce the semantic that requesting a check on a null global
5750     * permission is automatically denied.  (Internally a null permission
5751     * string is used when calling {@link #checkComponentPermission} in cases
5752     * when only uid-based security is needed.)
5753     *
5754     * This can be called with or without the global lock held.
5755     */
5756    @Override
5757    public int checkPermission(String permission, int pid, int uid) {
5758        if (permission == null) {
5759            return PackageManager.PERMISSION_DENIED;
5760        }
5761        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
5762    }
5763
5764    /**
5765     * Binder IPC calls go through the public entry point.
5766     * This can be called with or without the global lock held.
5767     */
5768    int checkCallingPermission(String permission) {
5769        return checkPermission(permission,
5770                Binder.getCallingPid(),
5771                UserHandle.getAppId(Binder.getCallingUid()));
5772    }
5773
5774    /**
5775     * This can be called with or without the global lock held.
5776     */
5777    void enforceCallingPermission(String permission, String func) {
5778        if (checkCallingPermission(permission)
5779                == PackageManager.PERMISSION_GRANTED) {
5780            return;
5781        }
5782
5783        String msg = "Permission Denial: " + func + " from pid="
5784                + Binder.getCallingPid()
5785                + ", uid=" + Binder.getCallingUid()
5786                + " requires " + permission;
5787        Slog.w(TAG, msg);
5788        throw new SecurityException(msg);
5789    }
5790
5791    /**
5792     * Determine if UID is holding permissions required to access {@link Uri} in
5793     * the given {@link ProviderInfo}. Final permission checking is always done
5794     * in {@link ContentProvider}.
5795     */
5796    private final boolean checkHoldingPermissionsLocked(
5797            IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
5798        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5799                "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
5800
5801        if (pi.applicationInfo.uid == uid) {
5802            return true;
5803        } else if (!pi.exported) {
5804            return false;
5805        }
5806
5807        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
5808        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
5809        try {
5810            // check if target holds top-level <provider> permissions
5811            if (!readMet && pi.readPermission != null
5812                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5813                readMet = true;
5814            }
5815            if (!writeMet && pi.writePermission != null
5816                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5817                writeMet = true;
5818            }
5819
5820            // track if unprotected read/write is allowed; any denied
5821            // <path-permission> below removes this ability
5822            boolean allowDefaultRead = pi.readPermission == null;
5823            boolean allowDefaultWrite = pi.writePermission == null;
5824
5825            // check if target holds any <path-permission> that match uri
5826            final PathPermission[] pps = pi.pathPermissions;
5827            if (pps != null) {
5828                final String path = uri.getPath();
5829                int i = pps.length;
5830                while (i > 0 && (!readMet || !writeMet)) {
5831                    i--;
5832                    PathPermission pp = pps[i];
5833                    if (pp.match(path)) {
5834                        if (!readMet) {
5835                            final String pprperm = pp.getReadPermission();
5836                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5837                                    + pprperm + " for " + pp.getPath()
5838                                    + ": match=" + pp.match(path)
5839                                    + " check=" + pm.checkUidPermission(pprperm, uid));
5840                            if (pprperm != null) {
5841                                if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5842                                    readMet = true;
5843                                } else {
5844                                    allowDefaultRead = false;
5845                                }
5846                            }
5847                        }
5848                        if (!writeMet) {
5849                            final String ppwperm = pp.getWritePermission();
5850                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5851                                    + ppwperm + " for " + pp.getPath()
5852                                    + ": match=" + pp.match(path)
5853                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
5854                            if (ppwperm != null) {
5855                                if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5856                                    writeMet = true;
5857                                } else {
5858                                    allowDefaultWrite = false;
5859                                }
5860                            }
5861                        }
5862                    }
5863                }
5864            }
5865
5866            // grant unprotected <provider> read/write, if not blocked by
5867            // <path-permission> above
5868            if (allowDefaultRead) readMet = true;
5869            if (allowDefaultWrite) writeMet = true;
5870
5871        } catch (RemoteException e) {
5872            return false;
5873        }
5874
5875        return readMet && writeMet;
5876    }
5877
5878    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
5879        ProviderInfo pi = null;
5880        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
5881        if (cpr != null) {
5882            pi = cpr.info;
5883        } else {
5884            try {
5885                pi = AppGlobals.getPackageManager().resolveContentProvider(
5886                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
5887            } catch (RemoteException ex) {
5888            }
5889        }
5890        return pi;
5891    }
5892
5893    private UriPermission findUriPermissionLocked(int targetUid, Uri uri) {
5894        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5895        if (targetUris != null) {
5896            return targetUris.get(uri);
5897        } else {
5898            return null;
5899        }
5900    }
5901
5902    private UriPermission findOrCreateUriPermissionLocked(
5903            String sourcePkg, String targetPkg, int targetUid, Uri uri) {
5904        ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
5905        if (targetUris == null) {
5906            targetUris = Maps.newArrayMap();
5907            mGrantedUriPermissions.put(targetUid, targetUris);
5908        }
5909
5910        UriPermission perm = targetUris.get(uri);
5911        if (perm == null) {
5912            perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri);
5913            targetUris.put(uri, perm);
5914        }
5915
5916        return perm;
5917    }
5918
5919    private final boolean checkUriPermissionLocked(
5920            Uri uri, int uid, int modeFlags, int minStrength) {
5921        // Root gets to do everything.
5922        if (uid == 0) {
5923            return true;
5924        }
5925        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5926        if (perms == null) return false;
5927        UriPermission perm = perms.get(uri);
5928        if (perm == null) return false;
5929        return perm.getStrength(modeFlags) >= minStrength;
5930    }
5931
5932    @Override
5933    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5934        enforceNotIsolatedCaller("checkUriPermission");
5935
5936        // Another redirected-binder-call permissions check as in
5937        // {@link checkComponentPermission}.
5938        Identity tlsIdentity = sCallerIdentity.get();
5939        if (tlsIdentity != null) {
5940            uid = tlsIdentity.uid;
5941            pid = tlsIdentity.pid;
5942        }
5943
5944        // Our own process gets to do everything.
5945        if (pid == MY_PID) {
5946            return PackageManager.PERMISSION_GRANTED;
5947        }
5948        synchronized(this) {
5949            return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED)
5950                    ? PackageManager.PERMISSION_GRANTED
5951                    : PackageManager.PERMISSION_DENIED;
5952        }
5953    }
5954
5955    /**
5956     * Check if the targetPkg can be granted permission to access uri by
5957     * the callingUid using the given modeFlags.  Throws a security exception
5958     * if callingUid is not allowed to do this.  Returns the uid of the target
5959     * if the URI permission grant should be performed; returns -1 if it is not
5960     * needed (for example targetPkg already has permission to access the URI).
5961     * If you already know the uid of the target, you can supply it in
5962     * lastTargetUid else set that to -1.
5963     */
5964    int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5965            Uri uri, int modeFlags, int lastTargetUid) {
5966        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
5967        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5968                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5969        if (modeFlags == 0) {
5970            return -1;
5971        }
5972
5973        if (targetPkg != null) {
5974            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5975                    "Checking grant " + targetPkg + " permission to " + uri);
5976        }
5977
5978        final IPackageManager pm = AppGlobals.getPackageManager();
5979
5980        // If this is not a content: uri, we can't do anything with it.
5981        if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5982            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5983                    "Can't grant URI permission for non-content URI: " + uri);
5984            return -1;
5985        }
5986
5987        final String authority = uri.getAuthority();
5988        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
5989        if (pi == null) {
5990            Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5991            return -1;
5992        }
5993
5994        int targetUid = lastTargetUid;
5995        if (targetUid < 0 && targetPkg != null) {
5996            try {
5997                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5998                if (targetUid < 0) {
5999                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6000                            "Can't grant URI permission no uid for: " + targetPkg);
6001                    return -1;
6002                }
6003            } catch (RemoteException ex) {
6004                return -1;
6005            }
6006        }
6007
6008        if (targetUid >= 0) {
6009            // First...  does the target actually need this permission?
6010            if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
6011                // No need to grant the target this permission.
6012                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6013                        "Target " + targetPkg + " already has full permission to " + uri);
6014                return -1;
6015            }
6016        } else {
6017            // First...  there is no target package, so can anyone access it?
6018            boolean allowed = pi.exported;
6019            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6020                if (pi.readPermission != null) {
6021                    allowed = false;
6022                }
6023            }
6024            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6025                if (pi.writePermission != null) {
6026                    allowed = false;
6027                }
6028            }
6029            if (allowed) {
6030                return -1;
6031            }
6032        }
6033
6034        // Second...  is the provider allowing granting of URI permissions?
6035        if (!pi.grantUriPermissions) {
6036            throw new SecurityException("Provider " + pi.packageName
6037                    + "/" + pi.name
6038                    + " does not allow granting of Uri permissions (uri "
6039                    + uri + ")");
6040        }
6041        if (pi.uriPermissionPatterns != null) {
6042            final int N = pi.uriPermissionPatterns.length;
6043            boolean allowed = false;
6044            for (int i=0; i<N; i++) {
6045                if (pi.uriPermissionPatterns[i] != null
6046                        && pi.uriPermissionPatterns[i].match(uri.getPath())) {
6047                    allowed = true;
6048                    break;
6049                }
6050            }
6051            if (!allowed) {
6052                throw new SecurityException("Provider " + pi.packageName
6053                        + "/" + pi.name
6054                        + " does not allow granting of permission to path of Uri "
6055                        + uri);
6056            }
6057        }
6058
6059        // Third...  does the caller itself have permission to access
6060        // this uri?
6061        if (callingUid != Process.myUid()) {
6062            if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6063                // Require they hold a strong enough Uri permission
6064                final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6065                        : UriPermission.STRENGTH_OWNED;
6066                if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) {
6067                    throw new SecurityException("Uid " + callingUid
6068                            + " does not have permission to uri " + uri);
6069                }
6070            }
6071        }
6072
6073        return targetUid;
6074    }
6075
6076    @Override
6077    public int checkGrantUriPermission(int callingUid, String targetPkg,
6078            Uri uri, int modeFlags) {
6079        enforceNotIsolatedCaller("checkGrantUriPermission");
6080        synchronized(this) {
6081            return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6082        }
6083    }
6084
6085    void grantUriPermissionUncheckedLocked(
6086            int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
6087        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6088        modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6089                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6090        if (modeFlags == 0) {
6091            return;
6092        }
6093
6094        // So here we are: the caller has the assumed permission
6095        // to the uri, and the target doesn't.  Let's now give this to
6096        // the target.
6097
6098        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6099                "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
6100
6101        final String authority = uri.getAuthority();
6102        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid));
6103        if (pi == null) {
6104            Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString());
6105            return;
6106        }
6107
6108        final UriPermission perm = findOrCreateUriPermissionLocked(
6109                pi.packageName, targetPkg, targetUid, uri);
6110        perm.grantModes(modeFlags, persistable, owner);
6111    }
6112
6113    void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
6114            int modeFlags, UriPermissionOwner owner) {
6115        if (targetPkg == null) {
6116            throw new NullPointerException("targetPkg");
6117        }
6118
6119        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
6120        if (targetUid < 0) {
6121            return;
6122        }
6123
6124        grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
6125    }
6126
6127    static class NeededUriGrants extends ArrayList<Uri> {
6128        final String targetPkg;
6129        final int targetUid;
6130        final int flags;
6131
6132        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6133            this.targetPkg = targetPkg;
6134            this.targetUid = targetUid;
6135            this.flags = flags;
6136        }
6137    }
6138
6139    /**
6140     * Like checkGrantUriPermissionLocked, but takes an Intent.
6141     */
6142    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6143            String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
6144        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6145                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6146                + " clip=" + (intent != null ? intent.getClipData() : null)
6147                + " from " + intent + "; flags=0x"
6148                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6149
6150        if (targetPkg == null) {
6151            throw new NullPointerException("targetPkg");
6152        }
6153
6154        if (intent == null) {
6155            return null;
6156        }
6157        Uri data = intent.getData();
6158        ClipData clip = intent.getClipData();
6159        if (data == null && clip == null) {
6160            return null;
6161        }
6162
6163        if (data != null) {
6164            int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
6165                mode, needed != null ? needed.targetUid : -1);
6166            if (targetUid > 0) {
6167                if (needed == null) {
6168                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6169                }
6170                needed.add(data);
6171            }
6172        }
6173        if (clip != null) {
6174            for (int i=0; i<clip.getItemCount(); i++) {
6175                Uri uri = clip.getItemAt(i).getUri();
6176                if (uri != null) {
6177                    int targetUid = -1;
6178                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
6179                            mode, needed != null ? needed.targetUid : -1);
6180                    if (targetUid > 0) {
6181                        if (needed == null) {
6182                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6183                        }
6184                        needed.add(uri);
6185                    }
6186                } else {
6187                    Intent clipIntent = clip.getItemAt(i).getIntent();
6188                    if (clipIntent != null) {
6189                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6190                                callingUid, targetPkg, clipIntent, mode, needed);
6191                        if (newNeeded != null) {
6192                            needed = newNeeded;
6193                        }
6194                    }
6195                }
6196            }
6197        }
6198
6199        return needed;
6200    }
6201
6202    /**
6203     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6204     */
6205    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6206            UriPermissionOwner owner) {
6207        if (needed != null) {
6208            for (int i=0; i<needed.size(); i++) {
6209                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6210                        needed.get(i), needed.flags, owner);
6211            }
6212        }
6213    }
6214
6215    void grantUriPermissionFromIntentLocked(int callingUid,
6216            String targetPkg, Intent intent, UriPermissionOwner owner) {
6217        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6218                intent, intent != null ? intent.getFlags() : 0, null);
6219        if (needed == null) {
6220            return;
6221        }
6222
6223        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6224    }
6225
6226    @Override
6227    public void grantUriPermission(IApplicationThread caller, String targetPkg,
6228            Uri uri, int modeFlags) {
6229        enforceNotIsolatedCaller("grantUriPermission");
6230        synchronized(this) {
6231            final ProcessRecord r = getRecordForAppLocked(caller);
6232            if (r == null) {
6233                throw new SecurityException("Unable to find app for caller "
6234                        + caller
6235                        + " when granting permission to uri " + uri);
6236            }
6237            if (targetPkg == null) {
6238                throw new IllegalArgumentException("null target");
6239            }
6240            if (uri == null) {
6241                throw new IllegalArgumentException("null uri");
6242            }
6243
6244            // Persistable only supported through Intents
6245            Preconditions.checkFlagsArgument(modeFlags,
6246                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6247
6248            grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
6249                    null);
6250        }
6251    }
6252
6253    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6254        if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
6255                |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
6256            ArrayMap<Uri, UriPermission> perms
6257                    = mGrantedUriPermissions.get(perm.targetUid);
6258            if (perms != null) {
6259                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6260                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6261                perms.remove(perm.uri);
6262                if (perms.size() == 0) {
6263                    mGrantedUriPermissions.remove(perm.targetUid);
6264                }
6265            }
6266        }
6267    }
6268
6269    private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) {
6270        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri);
6271
6272        final IPackageManager pm = AppGlobals.getPackageManager();
6273        final String authority = uri.getAuthority();
6274        final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid));
6275        if (pi == null) {
6276            Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
6277            return;
6278        }
6279
6280        // Does the caller have this permission on the URI?
6281        if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
6282            // Right now, if you are not the original owner of the permission,
6283            // you are not allowed to revoke it.
6284            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6285                throw new SecurityException("Uid " + callingUid
6286                        + " does not have permission to uri " + uri);
6287            //}
6288        }
6289
6290        boolean persistChanged = false;
6291
6292        // Go through all of the permissions and remove any that match.
6293        final List<String> SEGMENTS = uri.getPathSegments();
6294        if (SEGMENTS != null) {
6295            final int NS = SEGMENTS.size();
6296            int N = mGrantedUriPermissions.size();
6297            for (int i=0; i<N; i++) {
6298                ArrayMap<Uri, UriPermission> perms
6299                        = mGrantedUriPermissions.valueAt(i);
6300                Iterator<UriPermission> it = perms.values().iterator();
6301            toploop:
6302                while (it.hasNext()) {
6303                    UriPermission perm = it.next();
6304                    Uri targetUri = perm.uri;
6305                    if (!authority.equals(targetUri.getAuthority())) {
6306                        continue;
6307                    }
6308                    List<String> targetSegments = targetUri.getPathSegments();
6309                    if (targetSegments == null) {
6310                        continue;
6311                    }
6312                    if (targetSegments.size() < NS) {
6313                        continue;
6314                    }
6315                    for (int j=0; j<NS; j++) {
6316                        if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
6317                            continue toploop;
6318                        }
6319                    }
6320                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6321                            "Revoking " + perm.targetUid + " permission to " + perm.uri);
6322                    persistChanged |= perm.clearModes(modeFlags, true);
6323                    if (perm.modeFlags == 0) {
6324                        it.remove();
6325                    }
6326                }
6327                if (perms.size() == 0) {
6328                    mGrantedUriPermissions.remove(
6329                            mGrantedUriPermissions.keyAt(i));
6330                    N--;
6331                    i--;
6332                }
6333            }
6334        }
6335
6336        if (persistChanged) {
6337            schedulePersistUriGrants();
6338        }
6339    }
6340
6341    @Override
6342    public void revokeUriPermission(IApplicationThread caller, Uri uri,
6343            int modeFlags) {
6344        enforceNotIsolatedCaller("revokeUriPermission");
6345        synchronized(this) {
6346            final ProcessRecord r = getRecordForAppLocked(caller);
6347            if (r == null) {
6348                throw new SecurityException("Unable to find app for caller "
6349                        + caller
6350                        + " when revoking permission to uri " + uri);
6351            }
6352            if (uri == null) {
6353                Slog.w(TAG, "revokeUriPermission: null uri");
6354                return;
6355            }
6356
6357            modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
6358                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6359            if (modeFlags == 0) {
6360                return;
6361            }
6362
6363            final IPackageManager pm = AppGlobals.getPackageManager();
6364            final String authority = uri.getAuthority();
6365            final ProviderInfo pi = getProviderInfoLocked(authority, r.userId);
6366            if (pi == null) {
6367                Slog.w(TAG, "No content provider found for permission revoke: "
6368                        + uri.toSafeString());
6369                return;
6370            }
6371
6372            revokeUriPermissionLocked(r.uid, uri, modeFlags);
6373        }
6374    }
6375
6376    /**
6377     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6378     * given package.
6379     *
6380     * @param packageName Package name to match, or {@code null} to apply to all
6381     *            packages.
6382     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6383     *            to all users.
6384     * @param persistable If persistable grants should be removed.
6385     */
6386    private void removeUriPermissionsForPackageLocked(
6387            String packageName, int userHandle, boolean persistable) {
6388        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6389            throw new IllegalArgumentException("Must narrow by either package or user");
6390        }
6391
6392        boolean persistChanged = false;
6393
6394        final int size = mGrantedUriPermissions.size();
6395        for (int i = 0; i < size; i++) {
6396            // Only inspect grants matching user
6397            if (userHandle == UserHandle.USER_ALL
6398                    || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) {
6399                final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i)
6400                        .values().iterator();
6401                while (it.hasNext()) {
6402                    final UriPermission perm = it.next();
6403
6404                    // Only inspect grants matching package
6405                    if (packageName == null || perm.sourcePkg.equals(packageName)
6406                            || perm.targetPkg.equals(packageName)) {
6407                        persistChanged |= perm.clearModes(~0, persistable);
6408
6409                        // Only remove when no modes remain; any persisted grants
6410                        // will keep this alive.
6411                        if (perm.modeFlags == 0) {
6412                            it.remove();
6413                        }
6414                    }
6415                }
6416            }
6417        }
6418
6419        if (persistChanged) {
6420            schedulePersistUriGrants();
6421        }
6422    }
6423
6424    @Override
6425    public IBinder newUriPermissionOwner(String name) {
6426        enforceNotIsolatedCaller("newUriPermissionOwner");
6427        synchronized(this) {
6428            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6429            return owner.getExternalTokenLocked();
6430        }
6431    }
6432
6433    @Override
6434    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
6435            Uri uri, int modeFlags) {
6436        synchronized(this) {
6437            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6438            if (owner == null) {
6439                throw new IllegalArgumentException("Unknown owner: " + token);
6440            }
6441            if (fromUid != Binder.getCallingUid()) {
6442                if (Binder.getCallingUid() != Process.myUid()) {
6443                    // Only system code can grant URI permissions on behalf
6444                    // of other users.
6445                    throw new SecurityException("nice try");
6446                }
6447            }
6448            if (targetPkg == null) {
6449                throw new IllegalArgumentException("null target");
6450            }
6451            if (uri == null) {
6452                throw new IllegalArgumentException("null uri");
6453            }
6454
6455            grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
6456        }
6457    }
6458
6459    @Override
6460    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
6461        synchronized(this) {
6462            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6463            if (owner == null) {
6464                throw new IllegalArgumentException("Unknown owner: " + token);
6465            }
6466
6467            if (uri == null) {
6468                owner.removeUriPermissionsLocked(mode);
6469            } else {
6470                owner.removeUriPermissionLocked(uri, mode);
6471            }
6472        }
6473    }
6474
6475    private void schedulePersistUriGrants() {
6476        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6477            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6478                    10 * DateUtils.SECOND_IN_MILLIS);
6479        }
6480    }
6481
6482    private void writeGrantedUriPermissions() {
6483        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6484
6485        // Snapshot permissions so we can persist without lock
6486        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6487        synchronized (this) {
6488            final int size = mGrantedUriPermissions.size();
6489            for (int i = 0 ; i < size; i++) {
6490                for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) {
6491                    if (perm.persistedModeFlags != 0) {
6492                        persist.add(perm.snapshot());
6493                    }
6494                }
6495            }
6496        }
6497
6498        FileOutputStream fos = null;
6499        try {
6500            fos = mGrantFile.startWrite();
6501
6502            XmlSerializer out = new FastXmlSerializer();
6503            out.setOutput(fos, "utf-8");
6504            out.startDocument(null, true);
6505            out.startTag(null, TAG_URI_GRANTS);
6506            for (UriPermission.Snapshot perm : persist) {
6507                out.startTag(null, TAG_URI_GRANT);
6508                writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle);
6509                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6510                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6511                out.attribute(null, ATTR_URI, String.valueOf(perm.uri));
6512                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6513                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6514                out.endTag(null, TAG_URI_GRANT);
6515            }
6516            out.endTag(null, TAG_URI_GRANTS);
6517            out.endDocument();
6518
6519            mGrantFile.finishWrite(fos);
6520        } catch (IOException e) {
6521            if (fos != null) {
6522                mGrantFile.failWrite(fos);
6523            }
6524        }
6525    }
6526
6527    private void readGrantedUriPermissionsLocked() {
6528        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6529
6530        final long now = System.currentTimeMillis();
6531
6532        FileInputStream fis = null;
6533        try {
6534            fis = mGrantFile.openRead();
6535            final XmlPullParser in = Xml.newPullParser();
6536            in.setInput(fis, null);
6537
6538            int type;
6539            while ((type = in.next()) != END_DOCUMENT) {
6540                final String tag = in.getName();
6541                if (type == START_TAG) {
6542                    if (TAG_URI_GRANT.equals(tag)) {
6543                        final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE);
6544                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6545                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6546                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6547                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6548                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6549
6550                        // Sanity check that provider still belongs to source package
6551                        final ProviderInfo pi = getProviderInfoLocked(
6552                                uri.getAuthority(), userHandle);
6553                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6554                            int targetUid = -1;
6555                            try {
6556                                targetUid = AppGlobals.getPackageManager()
6557                                        .getPackageUid(targetPkg, userHandle);
6558                            } catch (RemoteException e) {
6559                            }
6560                            if (targetUid != -1) {
6561                                final UriPermission perm = findOrCreateUriPermissionLocked(
6562                                        sourcePkg, targetPkg, targetUid, uri);
6563                                perm.initPersistedModes(modeFlags, createdTime);
6564                            }
6565                        } else {
6566                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6567                                    + " but instead found " + pi);
6568                        }
6569                    }
6570                }
6571            }
6572        } catch (FileNotFoundException e) {
6573            // Missing grants is okay
6574        } catch (IOException e) {
6575            Log.wtf(TAG, "Failed reading Uri grants", e);
6576        } catch (XmlPullParserException e) {
6577            Log.wtf(TAG, "Failed reading Uri grants", e);
6578        } finally {
6579            IoUtils.closeQuietly(fis);
6580        }
6581    }
6582
6583    @Override
6584    public void takePersistableUriPermission(Uri uri, int modeFlags) {
6585        enforceNotIsolatedCaller("takePersistableUriPermission");
6586
6587        Preconditions.checkFlagsArgument(modeFlags,
6588                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6589
6590        synchronized (this) {
6591            final int callingUid = Binder.getCallingUid();
6592            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6593            if (perm == null) {
6594                throw new SecurityException("No permission grant found for UID " + callingUid
6595                        + " and Uri " + uri.toSafeString());
6596            }
6597
6598            boolean persistChanged = perm.takePersistableModes(modeFlags);
6599            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
6600
6601            if (persistChanged) {
6602                schedulePersistUriGrants();
6603            }
6604        }
6605    }
6606
6607    @Override
6608    public void releasePersistableUriPermission(Uri uri, int modeFlags) {
6609        enforceNotIsolatedCaller("releasePersistableUriPermission");
6610
6611        Preconditions.checkFlagsArgument(modeFlags,
6612                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6613
6614        synchronized (this) {
6615            final int callingUid = Binder.getCallingUid();
6616
6617            final UriPermission perm = findUriPermissionLocked(callingUid, uri);
6618            if (perm == null) {
6619                Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri "
6620                        + uri.toSafeString());
6621                return;
6622            }
6623
6624            final boolean persistChanged = perm.releasePersistableModes(modeFlags);
6625            removeUriPermissionIfNeededLocked(perm);
6626            if (persistChanged) {
6627                schedulePersistUriGrants();
6628            }
6629        }
6630    }
6631
6632    /**
6633     * Prune any older {@link UriPermission} for the given UID until outstanding
6634     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
6635     *
6636     * @return if any mutations occured that require persisting.
6637     */
6638    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
6639        final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6640        if (perms == null) return false;
6641        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
6642
6643        final ArrayList<UriPermission> persisted = Lists.newArrayList();
6644        for (UriPermission perm : perms.values()) {
6645            if (perm.persistedModeFlags != 0) {
6646                persisted.add(perm);
6647            }
6648        }
6649
6650        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
6651        if (trimCount <= 0) return false;
6652
6653        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
6654        for (int i = 0; i < trimCount; i++) {
6655            final UriPermission perm = persisted.get(i);
6656
6657            if (DEBUG_URI_PERMISSION) {
6658                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
6659            }
6660
6661            perm.releasePersistableModes(~0);
6662            removeUriPermissionIfNeededLocked(perm);
6663        }
6664
6665        return true;
6666    }
6667
6668    @Override
6669    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
6670            String packageName, boolean incoming) {
6671        enforceNotIsolatedCaller("getPersistedUriPermissions");
6672        Preconditions.checkNotNull(packageName, "packageName");
6673
6674        final int callingUid = Binder.getCallingUid();
6675        final IPackageManager pm = AppGlobals.getPackageManager();
6676        try {
6677            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
6678            if (packageUid != callingUid) {
6679                throw new SecurityException(
6680                        "Package " + packageName + " does not belong to calling UID " + callingUid);
6681            }
6682        } catch (RemoteException e) {
6683            throw new SecurityException("Failed to verify package name ownership");
6684        }
6685
6686        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
6687        synchronized (this) {
6688            if (incoming) {
6689                final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6690                if (perms == null) {
6691                    Slog.w(TAG, "No permission grants found for " + packageName);
6692                } else {
6693                    final int size = perms.size();
6694                    for (int i = 0; i < size; i++) {
6695                        final UriPermission perm = perms.valueAt(i);
6696                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
6697                            result.add(perm.buildPersistedPublicApiObject());
6698                        }
6699                    }
6700                }
6701            } else {
6702                final int size = mGrantedUriPermissions.size();
6703                for (int i = 0; i < size; i++) {
6704                    final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6705                    final int permsSize = perms.size();
6706                    for (int j = 0; j < permsSize; j++) {
6707                        final UriPermission perm = perms.valueAt(j);
6708                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
6709                            result.add(perm.buildPersistedPublicApiObject());
6710                        }
6711                    }
6712                }
6713            }
6714        }
6715        return new ParceledListSlice<android.content.UriPermission>(result);
6716    }
6717
6718    @Override
6719    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
6720        synchronized (this) {
6721            ProcessRecord app =
6722                who != null ? getRecordForAppLocked(who) : null;
6723            if (app == null) return;
6724
6725            Message msg = Message.obtain();
6726            msg.what = WAIT_FOR_DEBUGGER_MSG;
6727            msg.obj = app;
6728            msg.arg1 = waiting ? 1 : 0;
6729            mHandler.sendMessage(msg);
6730        }
6731    }
6732
6733    @Override
6734    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
6735        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
6736        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
6737        outInfo.availMem = Process.getFreeMemory();
6738        outInfo.totalMem = Process.getTotalMemory();
6739        outInfo.threshold = homeAppMem;
6740        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
6741        outInfo.hiddenAppThreshold = cachedAppMem;
6742        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
6743                ProcessList.SERVICE_ADJ);
6744        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
6745                ProcessList.VISIBLE_APP_ADJ);
6746        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
6747                ProcessList.FOREGROUND_APP_ADJ);
6748    }
6749
6750    // =========================================================
6751    // TASK MANAGEMENT
6752    // =========================================================
6753
6754    @Override
6755    public List<RunningTaskInfo> getTasks(int maxNum, int flags,
6756                         IThumbnailReceiver receiver) {
6757        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
6758
6759        PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
6760        ActivityRecord topRecord = null;
6761
6762        synchronized(this) {
6763            if (localLOGV) Slog.v(
6764                TAG, "getTasks: max=" + maxNum + ", flags=" + flags
6765                + ", receiver=" + receiver);
6766
6767            if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
6768                    != PackageManager.PERMISSION_GRANTED) {
6769                if (receiver != null) {
6770                    // If the caller wants to wait for pending thumbnails,
6771                    // it ain't gonna get them.
6772                    try {
6773                        receiver.finished();
6774                    } catch (RemoteException ex) {
6775                    }
6776                }
6777                String msg = "Permission Denial: getTasks() from pid="
6778                        + Binder.getCallingPid()
6779                        + ", uid=" + Binder.getCallingUid()
6780                        + " requires " + android.Manifest.permission.GET_TASKS;
6781                Slog.w(TAG, msg);
6782                throw new SecurityException(msg);
6783            }
6784
6785            // TODO: Improve with MRU list from all ActivityStacks.
6786            topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list);
6787
6788            if (!pending.pendingRecords.isEmpty()) {
6789                mPendingThumbnails.add(pending);
6790            }
6791        }
6792
6793        if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
6794
6795        if (topRecord != null) {
6796            if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
6797            try {
6798                IApplicationThread topThumbnail = topRecord.app.thread;
6799                topThumbnail.requestThumbnail(topRecord.appToken);
6800            } catch (Exception e) {
6801                Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
6802                sendPendingThumbnail(null, topRecord.appToken, null, null, true);
6803            }
6804        }
6805
6806        if (pending == null && receiver != null) {
6807            // In this case all thumbnails were available and the client
6808            // is being asked to be told when the remaining ones come in...
6809            // which is unusually, since the top-most currently running
6810            // activity should never have a canned thumbnail!  Oh well.
6811            try {
6812                receiver.finished();
6813            } catch (RemoteException ex) {
6814            }
6815        }
6816
6817        return list;
6818    }
6819
6820    TaskRecord getMostRecentTask() {
6821        return mRecentTasks.get(0);
6822    }
6823
6824    @Override
6825    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
6826            int flags, int userId) {
6827        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6828                false, true, "getRecentTasks", null);
6829
6830        synchronized (this) {
6831            enforceCallingPermission(android.Manifest.permission.GET_TASKS,
6832                    "getRecentTasks()");
6833            final boolean detailed = checkCallingPermission(
6834                    android.Manifest.permission.GET_DETAILED_TASKS)
6835                    == PackageManager.PERMISSION_GRANTED;
6836
6837            IPackageManager pm = AppGlobals.getPackageManager();
6838
6839            final int N = mRecentTasks.size();
6840            ArrayList<ActivityManager.RecentTaskInfo> res
6841                    = new ArrayList<ActivityManager.RecentTaskInfo>(
6842                            maxNum < N ? maxNum : N);
6843            for (int i=0; i<N && maxNum > 0; i++) {
6844                TaskRecord tr = mRecentTasks.get(i);
6845                // Only add calling user's recent tasks
6846                if (tr.userId != userId) continue;
6847                // Return the entry if desired by the caller.  We always return
6848                // the first entry, because callers always expect this to be the
6849                // foreground app.  We may filter others if the caller has
6850                // not supplied RECENT_WITH_EXCLUDED and there is some reason
6851                // we should exclude the entry.
6852
6853                if (i == 0
6854                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
6855                        || (tr.intent == null)
6856                        || ((tr.intent.getFlags()
6857                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
6858                    ActivityManager.RecentTaskInfo rti
6859                            = new ActivityManager.RecentTaskInfo();
6860                    rti.id = tr.numActivities > 0 ? tr.taskId : -1;
6861                    rti.persistentId = tr.taskId;
6862                    rti.baseIntent = new Intent(
6863                            tr.intent != null ? tr.intent : tr.affinityIntent);
6864                    if (!detailed) {
6865                        rti.baseIntent.replaceExtras((Bundle)null);
6866                    }
6867                    rti.origActivity = tr.origActivity;
6868                    rti.description = tr.lastDescription;
6869                    rti.stackId = tr.stack.mStackId;
6870
6871                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
6872                        // Check whether this activity is currently available.
6873                        try {
6874                            if (rti.origActivity != null) {
6875                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
6876                                        == null) {
6877                                    continue;
6878                                }
6879                            } else if (rti.baseIntent != null) {
6880                                if (pm.queryIntentActivities(rti.baseIntent,
6881                                        null, 0, userId) == null) {
6882                                    continue;
6883                                }
6884                            }
6885                        } catch (RemoteException e) {
6886                            // Will never happen.
6887                        }
6888                    }
6889
6890                    res.add(rti);
6891                    maxNum--;
6892                }
6893            }
6894            return res;
6895        }
6896    }
6897
6898    private TaskRecord recentTaskForIdLocked(int id) {
6899        final int N = mRecentTasks.size();
6900            for (int i=0; i<N; i++) {
6901                TaskRecord tr = mRecentTasks.get(i);
6902                if (tr.taskId == id) {
6903                    return tr;
6904                }
6905            }
6906            return null;
6907    }
6908
6909    @Override
6910    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
6911        synchronized (this) {
6912            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6913                    "getTaskThumbnails()");
6914            TaskRecord tr = recentTaskForIdLocked(id);
6915            if (tr != null) {
6916                return tr.getTaskThumbnailsLocked();
6917            }
6918        }
6919        return null;
6920    }
6921
6922    @Override
6923    public Bitmap getTaskTopThumbnail(int id) {
6924        synchronized (this) {
6925            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
6926                    "getTaskTopThumbnail()");
6927            TaskRecord tr = recentTaskForIdLocked(id);
6928            if (tr != null) {
6929                return tr.getTaskTopThumbnailLocked();
6930            }
6931        }
6932        return null;
6933    }
6934
6935    @Override
6936    public boolean removeSubTask(int taskId, int subTaskIndex) {
6937        synchronized (this) {
6938            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
6939                    "removeSubTask()");
6940            long ident = Binder.clearCallingIdentity();
6941            try {
6942                TaskRecord tr = recentTaskForIdLocked(taskId);
6943                if (tr != null) {
6944                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
6945                }
6946                return false;
6947            } finally {
6948                Binder.restoreCallingIdentity(ident);
6949            }
6950        }
6951    }
6952
6953    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
6954        if (!pr.killedByAm) {
6955            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
6956            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
6957                    pr.processName, pr.setAdj, reason);
6958            pr.killedByAm = true;
6959            Process.killProcessQuiet(pr.pid);
6960        }
6961    }
6962
6963    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
6964        tr.disposeThumbnail();
6965        mRecentTasks.remove(tr);
6966        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
6967        Intent baseIntent = new Intent(
6968                tr.intent != null ? tr.intent : tr.affinityIntent);
6969        ComponentName component = baseIntent.getComponent();
6970        if (component == null) {
6971            Slog.w(TAG, "Now component for base intent of task: " + tr);
6972            return;
6973        }
6974
6975        // Find any running services associated with this app.
6976        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
6977
6978        if (killProcesses) {
6979            // Find any running processes associated with this app.
6980            final String pkg = component.getPackageName();
6981            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
6982            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
6983            for (int i=0; i<pmap.size(); i++) {
6984                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
6985                for (int j=0; j<uids.size(); j++) {
6986                    ProcessRecord proc = uids.valueAt(j);
6987                    if (proc.userId != tr.userId) {
6988                        continue;
6989                    }
6990                    if (!proc.pkgList.containsKey(pkg)) {
6991                        continue;
6992                    }
6993                    procs.add(proc);
6994                }
6995            }
6996
6997            // Kill the running processes.
6998            for (int i=0; i<procs.size(); i++) {
6999                ProcessRecord pr = procs.get(i);
7000                if (pr == mHomeProcess) {
7001                    // Don't kill the home process along with tasks from the same package.
7002                    continue;
7003                }
7004                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7005                    killUnneededProcessLocked(pr, "remove task");
7006                } else {
7007                    pr.waitingToKill = "remove task";
7008                }
7009            }
7010        }
7011    }
7012
7013    @Override
7014    public boolean removeTask(int taskId, int flags) {
7015        synchronized (this) {
7016            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7017                    "removeTask()");
7018            long ident = Binder.clearCallingIdentity();
7019            try {
7020                TaskRecord tr = recentTaskForIdLocked(taskId);
7021                if (tr != null) {
7022                    ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false);
7023                    if (r != null) {
7024                        cleanUpRemovedTaskLocked(tr, flags);
7025                        return true;
7026                    }
7027                    if (tr.mActivities.size() == 0) {
7028                        // Caller is just removing a recent task that is
7029                        // not actively running.  That is easy!
7030                        cleanUpRemovedTaskLocked(tr, flags);
7031                        return true;
7032                    }
7033                    Slog.w(TAG, "removeTask: task " + taskId
7034                            + " does not have activities to remove, "
7035                            + " but numActivities=" + tr.numActivities
7036                            + ": " + tr);
7037                }
7038            } finally {
7039                Binder.restoreCallingIdentity(ident);
7040            }
7041        }
7042        return false;
7043    }
7044
7045    /**
7046     * TODO: Add mController hook
7047     */
7048    @Override
7049    public void moveTaskToFront(int task, int flags, Bundle options) {
7050        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7051                "moveTaskToFront()");
7052
7053        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
7054        synchronized(this) {
7055            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7056                    Binder.getCallingUid(), "Task to front")) {
7057                ActivityOptions.abort(options);
7058                return;
7059            }
7060            final long origId = Binder.clearCallingIdentity();
7061            try {
7062                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7063            } finally {
7064                Binder.restoreCallingIdentity(origId);
7065            }
7066            ActivityOptions.abort(options);
7067        }
7068    }
7069
7070    @Override
7071    public void moveTaskToBack(int taskId) {
7072        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7073                "moveTaskToBack()");
7074
7075        synchronized(this) {
7076            TaskRecord tr = recentTaskForIdLocked(taskId);
7077            if (tr != null) {
7078                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7079                ActivityStack stack = tr.stack;
7080                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7081                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7082                            Binder.getCallingUid(), "Task to back")) {
7083                        return;
7084                    }
7085                }
7086                final long origId = Binder.clearCallingIdentity();
7087                try {
7088                    stack.moveTaskToBackLocked(taskId, null);
7089                } finally {
7090                    Binder.restoreCallingIdentity(origId);
7091                }
7092            }
7093        }
7094    }
7095
7096    /**
7097     * Moves an activity, and all of the other activities within the same task, to the bottom
7098     * of the history stack.  The activity's order within the task is unchanged.
7099     *
7100     * @param token A reference to the activity we wish to move
7101     * @param nonRoot If false then this only works if the activity is the root
7102     *                of a task; if true it will work for any activity in a task.
7103     * @return Returns true if the move completed, false if not.
7104     */
7105    @Override
7106    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7107        enforceNotIsolatedCaller("moveActivityTaskToBack");
7108        synchronized(this) {
7109            final long origId = Binder.clearCallingIdentity();
7110            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7111            if (taskId >= 0) {
7112                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7113            }
7114            Binder.restoreCallingIdentity(origId);
7115        }
7116        return false;
7117    }
7118
7119    @Override
7120    public void moveTaskBackwards(int task) {
7121        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7122                "moveTaskBackwards()");
7123
7124        synchronized(this) {
7125            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7126                    Binder.getCallingUid(), "Task backwards")) {
7127                return;
7128            }
7129            final long origId = Binder.clearCallingIdentity();
7130            moveTaskBackwardsLocked(task);
7131            Binder.restoreCallingIdentity(origId);
7132        }
7133    }
7134
7135    private final void moveTaskBackwardsLocked(int task) {
7136        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7137    }
7138
7139    @Override
7140    public IBinder getHomeActivityToken() throws RemoteException {
7141        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7142                "getHomeActivityToken()");
7143        synchronized (this) {
7144            return mStackSupervisor.getHomeActivityToken();
7145        }
7146    }
7147
7148    @Override
7149    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7150            IActivityContainerCallback callback) throws RemoteException {
7151        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7152                "createActivityContainer()");
7153        synchronized (this) {
7154            if (parentActivityToken == null) {
7155                throw new IllegalArgumentException("parent token must not be null");
7156            }
7157            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7158            if (r == null) {
7159                return null;
7160            }
7161            return mStackSupervisor.createActivityContainer(r, callback);
7162        }
7163    }
7164
7165    @Override
7166    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7167        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7168                "deleteActivityContainer()");
7169        synchronized (this) {
7170            mStackSupervisor.deleteActivityContainer(container);
7171        }
7172    }
7173
7174    @Override
7175    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7176            throws RemoteException {
7177        synchronized (this) {
7178            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7179            if (stack != null) {
7180                return stack.mActivityContainer;
7181            }
7182            return null;
7183        }
7184    }
7185
7186    @Override
7187    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7188        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7189                "moveTaskToStack()");
7190        if (stackId == HOME_STACK_ID) {
7191            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7192                    new RuntimeException("here").fillInStackTrace());
7193        }
7194        synchronized (this) {
7195            long ident = Binder.clearCallingIdentity();
7196            try {
7197                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7198                        + stackId + " toTop=" + toTop);
7199                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7200            } finally {
7201                Binder.restoreCallingIdentity(ident);
7202            }
7203        }
7204    }
7205
7206    @Override
7207    public void resizeStack(int stackBoxId, Rect bounds) {
7208        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7209                "resizeStackBox()");
7210        long ident = Binder.clearCallingIdentity();
7211        try {
7212            mWindowManager.resizeStack(stackBoxId, bounds);
7213        } finally {
7214            Binder.restoreCallingIdentity(ident);
7215        }
7216    }
7217
7218    @Override
7219    public List<StackInfo> getAllStackInfos() {
7220        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7221                "getAllStackInfos()");
7222        long ident = Binder.clearCallingIdentity();
7223        try {
7224            synchronized (this) {
7225                return mStackSupervisor.getAllStackInfosLocked();
7226            }
7227        } finally {
7228            Binder.restoreCallingIdentity(ident);
7229        }
7230    }
7231
7232    @Override
7233    public StackInfo getStackInfo(int stackId) {
7234        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7235                "getStackInfo()");
7236        long ident = Binder.clearCallingIdentity();
7237        try {
7238            synchronized (this) {
7239                return mStackSupervisor.getStackInfoLocked(stackId);
7240            }
7241        } finally {
7242            Binder.restoreCallingIdentity(ident);
7243        }
7244    }
7245
7246    @Override
7247    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7248        synchronized(this) {
7249            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7250        }
7251    }
7252
7253    // =========================================================
7254    // THUMBNAILS
7255    // =========================================================
7256
7257    public void reportThumbnail(IBinder token,
7258            Bitmap thumbnail, CharSequence description) {
7259        //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
7260        final long origId = Binder.clearCallingIdentity();
7261        sendPendingThumbnail(null, token, thumbnail, description, true);
7262        Binder.restoreCallingIdentity(origId);
7263    }
7264
7265    final void sendPendingThumbnail(ActivityRecord r, IBinder token,
7266            Bitmap thumbnail, CharSequence description, boolean always) {
7267        TaskRecord task;
7268        ArrayList<PendingThumbnailsRecord> receivers = null;
7269
7270        //System.out.println("Send pending thumbnail: " + r);
7271
7272        synchronized(this) {
7273            if (r == null) {
7274                r = ActivityRecord.isInStackLocked(token);
7275                if (r == null) {
7276                    return;
7277                }
7278            }
7279            if (thumbnail == null && r.thumbHolder != null) {
7280                thumbnail = r.thumbHolder.lastThumbnail;
7281                description = r.thumbHolder.lastDescription;
7282            }
7283            if (thumbnail == null && !always) {
7284                // If there is no thumbnail, and this entry is not actually
7285                // going away, then abort for now and pick up the next
7286                // thumbnail we get.
7287                return;
7288            }
7289            task = r.task;
7290
7291            int N = mPendingThumbnails.size();
7292            int i=0;
7293            while (i<N) {
7294                PendingThumbnailsRecord pr = mPendingThumbnails.get(i);
7295                //System.out.println("Looking in " + pr.pendingRecords);
7296                if (pr.pendingRecords.remove(r)) {
7297                    if (receivers == null) {
7298                        receivers = new ArrayList<PendingThumbnailsRecord>();
7299                    }
7300                    receivers.add(pr);
7301                    if (pr.pendingRecords.size() == 0) {
7302                        pr.finished = true;
7303                        mPendingThumbnails.remove(i);
7304                        N--;
7305                        continue;
7306                    }
7307                }
7308                i++;
7309            }
7310        }
7311
7312        if (receivers != null) {
7313            final int N = receivers.size();
7314            for (int i=0; i<N; i++) {
7315                try {
7316                    PendingThumbnailsRecord pr = receivers.get(i);
7317                    pr.receiver.newThumbnail(
7318                        task != null ? task.taskId : -1, thumbnail, description);
7319                    if (pr.finished) {
7320                        pr.receiver.finished();
7321                    }
7322                } catch (Exception e) {
7323                    Slog.w(TAG, "Exception thrown when sending thumbnail", e);
7324                }
7325            }
7326        }
7327    }
7328
7329    // =========================================================
7330    // CONTENT PROVIDERS
7331    // =========================================================
7332
7333    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7334        List<ProviderInfo> providers = null;
7335        try {
7336            providers = AppGlobals.getPackageManager().
7337                queryContentProviders(app.processName, app.uid,
7338                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7339        } catch (RemoteException ex) {
7340        }
7341        if (DEBUG_MU)
7342            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7343        int userId = app.userId;
7344        if (providers != null) {
7345            int N = providers.size();
7346            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7347            for (int i=0; i<N; i++) {
7348                ProviderInfo cpi =
7349                    (ProviderInfo)providers.get(i);
7350                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7351                        cpi.name, cpi.flags);
7352                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7353                    // This is a singleton provider, but a user besides the
7354                    // default user is asking to initialize a process it runs
7355                    // in...  well, no, it doesn't actually run in this process,
7356                    // it runs in the process of the default user.  Get rid of it.
7357                    providers.remove(i);
7358                    N--;
7359                    i--;
7360                    continue;
7361                }
7362
7363                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7364                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7365                if (cpr == null) {
7366                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7367                    mProviderMap.putProviderByClass(comp, cpr);
7368                }
7369                if (DEBUG_MU)
7370                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7371                app.pubProviders.put(cpi.name, cpr);
7372                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7373                    // Don't add this if it is a platform component that is marked
7374                    // to run in multiple processes, because this is actually
7375                    // part of the framework so doesn't make sense to track as a
7376                    // separate apk in the process.
7377                    app.addPackage(cpi.applicationInfo.packageName, mProcessStats);
7378                }
7379                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7380            }
7381        }
7382        return providers;
7383    }
7384
7385    /**
7386     * Check if {@link ProcessRecord} has a possible chance at accessing the
7387     * given {@link ProviderInfo}. Final permission checking is always done
7388     * in {@link ContentProvider}.
7389     */
7390    private final String checkContentProviderPermissionLocked(
7391            ProviderInfo cpi, ProcessRecord r) {
7392        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7393        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7394        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7395                cpi.applicationInfo.uid, cpi.exported)
7396                == PackageManager.PERMISSION_GRANTED) {
7397            return null;
7398        }
7399        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7400                cpi.applicationInfo.uid, cpi.exported)
7401                == PackageManager.PERMISSION_GRANTED) {
7402            return null;
7403        }
7404
7405        PathPermission[] pps = cpi.pathPermissions;
7406        if (pps != null) {
7407            int i = pps.length;
7408            while (i > 0) {
7409                i--;
7410                PathPermission pp = pps[i];
7411                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7412                        cpi.applicationInfo.uid, cpi.exported)
7413                        == PackageManager.PERMISSION_GRANTED) {
7414                    return null;
7415                }
7416                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7417                        cpi.applicationInfo.uid, cpi.exported)
7418                        == PackageManager.PERMISSION_GRANTED) {
7419                    return null;
7420                }
7421            }
7422        }
7423
7424        ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7425        if (perms != null) {
7426            for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
7427                if (uri.getKey().getAuthority().equals(cpi.authority)) {
7428                    return null;
7429                }
7430            }
7431        }
7432
7433        String msg;
7434        if (!cpi.exported) {
7435            msg = "Permission Denial: opening provider " + cpi.name
7436                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7437                    + ", uid=" + callingUid + ") that is not exported from uid "
7438                    + cpi.applicationInfo.uid;
7439        } else {
7440            msg = "Permission Denial: opening provider " + cpi.name
7441                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7442                    + ", uid=" + callingUid + ") requires "
7443                    + cpi.readPermission + " or " + cpi.writePermission;
7444        }
7445        Slog.w(TAG, msg);
7446        return msg;
7447    }
7448
7449    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
7450            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7451        if (r != null) {
7452            for (int i=0; i<r.conProviders.size(); i++) {
7453                ContentProviderConnection conn = r.conProviders.get(i);
7454                if (conn.provider == cpr) {
7455                    if (DEBUG_PROVIDER) Slog.v(TAG,
7456                            "Adding provider requested by "
7457                            + r.processName + " from process "
7458                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7459                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7460                    if (stable) {
7461                        conn.stableCount++;
7462                        conn.numStableIncs++;
7463                    } else {
7464                        conn.unstableCount++;
7465                        conn.numUnstableIncs++;
7466                    }
7467                    return conn;
7468                }
7469            }
7470            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
7471            if (stable) {
7472                conn.stableCount = 1;
7473                conn.numStableIncs = 1;
7474            } else {
7475                conn.unstableCount = 1;
7476                conn.numUnstableIncs = 1;
7477            }
7478            cpr.connections.add(conn);
7479            r.conProviders.add(conn);
7480            return conn;
7481        }
7482        cpr.addExternalProcessHandleLocked(externalProcessToken);
7483        return null;
7484    }
7485
7486    boolean decProviderCountLocked(ContentProviderConnection conn,
7487            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
7488        if (conn != null) {
7489            cpr = conn.provider;
7490            if (DEBUG_PROVIDER) Slog.v(TAG,
7491                    "Removing provider requested by "
7492                    + conn.client.processName + " from process "
7493                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
7494                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
7495            if (stable) {
7496                conn.stableCount--;
7497            } else {
7498                conn.unstableCount--;
7499            }
7500            if (conn.stableCount == 0 && conn.unstableCount == 0) {
7501                cpr.connections.remove(conn);
7502                conn.client.conProviders.remove(conn);
7503                return true;
7504            }
7505            return false;
7506        }
7507        cpr.removeExternalProcessHandleLocked(externalProcessToken);
7508        return false;
7509    }
7510
7511    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
7512            String name, IBinder token, boolean stable, int userId) {
7513        ContentProviderRecord cpr;
7514        ContentProviderConnection conn = null;
7515        ProviderInfo cpi = null;
7516
7517        synchronized(this) {
7518            ProcessRecord r = null;
7519            if (caller != null) {
7520                r = getRecordForAppLocked(caller);
7521                if (r == null) {
7522                    throw new SecurityException(
7523                            "Unable to find app for caller " + caller
7524                          + " (pid=" + Binder.getCallingPid()
7525                          + ") when getting content provider " + name);
7526                }
7527            }
7528
7529            // First check if this content provider has been published...
7530            cpr = mProviderMap.getProviderByName(name, userId);
7531            boolean providerRunning = cpr != null;
7532            if (providerRunning) {
7533                cpi = cpr.info;
7534                String msg;
7535                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7536                    throw new SecurityException(msg);
7537                }
7538
7539                if (r != null && cpr.canRunHere(r)) {
7540                    // This provider has been published or is in the process
7541                    // of being published...  but it is also allowed to run
7542                    // in the caller's process, so don't make a connection
7543                    // and just let the caller instantiate its own instance.
7544                    ContentProviderHolder holder = cpr.newHolder(null);
7545                    // don't give caller the provider object, it needs
7546                    // to make its own.
7547                    holder.provider = null;
7548                    return holder;
7549                }
7550
7551                final long origId = Binder.clearCallingIdentity();
7552
7553                // In this case the provider instance already exists, so we can
7554                // return it right away.
7555                conn = incProviderCountLocked(r, cpr, token, stable);
7556                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
7557                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
7558                        // If this is a perceptible app accessing the provider,
7559                        // make sure to count it as being accessed and thus
7560                        // back up on the LRU list.  This is good because
7561                        // content providers are often expensive to start.
7562                        updateLruProcessLocked(cpr.proc, false, null);
7563                    }
7564                }
7565
7566                if (cpr.proc != null) {
7567                    if (false) {
7568                        if (cpr.name.flattenToShortString().equals(
7569                                "com.android.providers.calendar/.CalendarProvider2")) {
7570                            Slog.v(TAG, "****************** KILLING "
7571                                + cpr.name.flattenToShortString());
7572                            Process.killProcess(cpr.proc.pid);
7573                        }
7574                    }
7575                    boolean success = updateOomAdjLocked(cpr.proc);
7576                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
7577                    // NOTE: there is still a race here where a signal could be
7578                    // pending on the process even though we managed to update its
7579                    // adj level.  Not sure what to do about this, but at least
7580                    // the race is now smaller.
7581                    if (!success) {
7582                        // Uh oh...  it looks like the provider's process
7583                        // has been killed on us.  We need to wait for a new
7584                        // process to be started, and make sure its death
7585                        // doesn't kill our process.
7586                        Slog.i(TAG,
7587                                "Existing provider " + cpr.name.flattenToShortString()
7588                                + " is crashing; detaching " + r);
7589                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
7590                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
7591                        if (!lastRef) {
7592                            // This wasn't the last ref our process had on
7593                            // the provider...  we have now been killed, bail.
7594                            return null;
7595                        }
7596                        providerRunning = false;
7597                        conn = null;
7598                    }
7599                }
7600
7601                Binder.restoreCallingIdentity(origId);
7602            }
7603
7604            boolean singleton;
7605            if (!providerRunning) {
7606                try {
7607                    cpi = AppGlobals.getPackageManager().
7608                        resolveContentProvider(name,
7609                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
7610                } catch (RemoteException ex) {
7611                }
7612                if (cpi == null) {
7613                    return null;
7614                }
7615                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7616                        cpi.name, cpi.flags);
7617                if (singleton) {
7618                    userId = 0;
7619                }
7620                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
7621
7622                String msg;
7623                if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
7624                    throw new SecurityException(msg);
7625                }
7626
7627                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
7628                        && !cpi.processName.equals("system")) {
7629                    // If this content provider does not run in the system
7630                    // process, and the system is not yet ready to run other
7631                    // processes, then fail fast instead of hanging.
7632                    throw new IllegalArgumentException(
7633                            "Attempt to launch content provider before system ready");
7634                }
7635
7636                // Make sure that the user who owns this provider is started.  If not,
7637                // we don't want to allow it to run.
7638                if (mStartedUsers.get(userId) == null) {
7639                    Slog.w(TAG, "Unable to launch app "
7640                            + cpi.applicationInfo.packageName + "/"
7641                            + cpi.applicationInfo.uid + " for provider "
7642                            + name + ": user " + userId + " is stopped");
7643                    return null;
7644                }
7645
7646                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7647                cpr = mProviderMap.getProviderByClass(comp, userId);
7648                final boolean firstClass = cpr == null;
7649                if (firstClass) {
7650                    try {
7651                        ApplicationInfo ai =
7652                            AppGlobals.getPackageManager().
7653                                getApplicationInfo(
7654                                        cpi.applicationInfo.packageName,
7655                                        STOCK_PM_FLAGS, userId);
7656                        if (ai == null) {
7657                            Slog.w(TAG, "No package info for content provider "
7658                                    + cpi.name);
7659                            return null;
7660                        }
7661                        ai = getAppInfoForUser(ai, userId);
7662                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
7663                    } catch (RemoteException ex) {
7664                        // pm is in same process, this will never happen.
7665                    }
7666                }
7667
7668                if (r != null && cpr.canRunHere(r)) {
7669                    // If this is a multiprocess provider, then just return its
7670                    // info and allow the caller to instantiate it.  Only do
7671                    // this if the provider is the same user as the caller's
7672                    // process, or can run as root (so can be in any process).
7673                    return cpr.newHolder(null);
7674                }
7675
7676                if (DEBUG_PROVIDER) {
7677                    RuntimeException e = new RuntimeException("here");
7678                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
7679                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
7680                }
7681
7682                // This is single process, and our app is now connecting to it.
7683                // See if we are already in the process of launching this
7684                // provider.
7685                final int N = mLaunchingProviders.size();
7686                int i;
7687                for (i=0; i<N; i++) {
7688                    if (mLaunchingProviders.get(i) == cpr) {
7689                        break;
7690                    }
7691                }
7692
7693                // If the provider is not already being launched, then get it
7694                // started.
7695                if (i >= N) {
7696                    final long origId = Binder.clearCallingIdentity();
7697
7698                    try {
7699                        // Content provider is now in use, its package can't be stopped.
7700                        try {
7701                            AppGlobals.getPackageManager().setPackageStoppedState(
7702                                    cpr.appInfo.packageName, false, userId);
7703                        } catch (RemoteException e) {
7704                        } catch (IllegalArgumentException e) {
7705                            Slog.w(TAG, "Failed trying to unstop package "
7706                                    + cpr.appInfo.packageName + ": " + e);
7707                        }
7708
7709                        // Use existing process if already started
7710                        ProcessRecord proc = getProcessRecordLocked(
7711                                cpi.processName, cpr.appInfo.uid, false);
7712                        if (proc != null && proc.thread != null) {
7713                            if (DEBUG_PROVIDER) {
7714                                Slog.d(TAG, "Installing in existing process " + proc);
7715                            }
7716                            proc.pubProviders.put(cpi.name, cpr);
7717                            try {
7718                                proc.thread.scheduleInstallProvider(cpi);
7719                            } catch (RemoteException e) {
7720                            }
7721                        } else {
7722                            proc = startProcessLocked(cpi.processName,
7723                                    cpr.appInfo, false, 0, "content provider",
7724                                    new ComponentName(cpi.applicationInfo.packageName,
7725                                            cpi.name), false, false, false);
7726                            if (proc == null) {
7727                                Slog.w(TAG, "Unable to launch app "
7728                                        + cpi.applicationInfo.packageName + "/"
7729                                        + cpi.applicationInfo.uid + " for provider "
7730                                        + name + ": process is bad");
7731                                return null;
7732                            }
7733                        }
7734                        cpr.launchingApp = proc;
7735                        mLaunchingProviders.add(cpr);
7736                    } finally {
7737                        Binder.restoreCallingIdentity(origId);
7738                    }
7739                }
7740
7741                // Make sure the provider is published (the same provider class
7742                // may be published under multiple names).
7743                if (firstClass) {
7744                    mProviderMap.putProviderByClass(comp, cpr);
7745                }
7746
7747                mProviderMap.putProviderByName(name, cpr);
7748                conn = incProviderCountLocked(r, cpr, token, stable);
7749                if (conn != null) {
7750                    conn.waiting = true;
7751                }
7752            }
7753        }
7754
7755        // Wait for the provider to be published...
7756        synchronized (cpr) {
7757            while (cpr.provider == null) {
7758                if (cpr.launchingApp == null) {
7759                    Slog.w(TAG, "Unable to launch app "
7760                            + cpi.applicationInfo.packageName + "/"
7761                            + cpi.applicationInfo.uid + " for provider "
7762                            + name + ": launching app became null");
7763                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
7764                            UserHandle.getUserId(cpi.applicationInfo.uid),
7765                            cpi.applicationInfo.packageName,
7766                            cpi.applicationInfo.uid, name);
7767                    return null;
7768                }
7769                try {
7770                    if (DEBUG_MU) {
7771                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
7772                                + cpr.launchingApp);
7773                    }
7774                    if (conn != null) {
7775                        conn.waiting = true;
7776                    }
7777                    cpr.wait();
7778                } catch (InterruptedException ex) {
7779                } finally {
7780                    if (conn != null) {
7781                        conn.waiting = false;
7782                    }
7783                }
7784            }
7785        }
7786        return cpr != null ? cpr.newHolder(conn) : null;
7787    }
7788
7789    public final ContentProviderHolder getContentProvider(
7790            IApplicationThread caller, String name, int userId, boolean stable) {
7791        enforceNotIsolatedCaller("getContentProvider");
7792        if (caller == null) {
7793            String msg = "null IApplicationThread when getting content provider "
7794                    + name;
7795            Slog.w(TAG, msg);
7796            throw new SecurityException(msg);
7797        }
7798
7799        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7800                false, true, "getContentProvider", null);
7801        return getContentProviderImpl(caller, name, null, stable, userId);
7802    }
7803
7804    public ContentProviderHolder getContentProviderExternal(
7805            String name, int userId, IBinder token) {
7806        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7807            "Do not have permission in call getContentProviderExternal()");
7808        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
7809                false, true, "getContentProvider", null);
7810        return getContentProviderExternalUnchecked(name, token, userId);
7811    }
7812
7813    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
7814            IBinder token, int userId) {
7815        return getContentProviderImpl(null, name, token, true, userId);
7816    }
7817
7818    /**
7819     * Drop a content provider from a ProcessRecord's bookkeeping
7820     */
7821    public void removeContentProvider(IBinder connection, boolean stable) {
7822        enforceNotIsolatedCaller("removeContentProvider");
7823        long ident = Binder.clearCallingIdentity();
7824        try {
7825            synchronized (this) {
7826                ContentProviderConnection conn;
7827                try {
7828                    conn = (ContentProviderConnection)connection;
7829                } catch (ClassCastException e) {
7830                    String msg ="removeContentProvider: " + connection
7831                            + " not a ContentProviderConnection";
7832                    Slog.w(TAG, msg);
7833                    throw new IllegalArgumentException(msg);
7834                }
7835                if (conn == null) {
7836                    throw new NullPointerException("connection is null");
7837                }
7838                if (decProviderCountLocked(conn, null, null, stable)) {
7839                    updateOomAdjLocked();
7840                }
7841            }
7842        } finally {
7843            Binder.restoreCallingIdentity(ident);
7844        }
7845    }
7846
7847    public void removeContentProviderExternal(String name, IBinder token) {
7848        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
7849            "Do not have permission in call removeContentProviderExternal()");
7850        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
7851    }
7852
7853    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
7854        synchronized (this) {
7855            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
7856            if(cpr == null) {
7857                //remove from mProvidersByClass
7858                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
7859                return;
7860            }
7861
7862            //update content provider record entry info
7863            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
7864            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
7865            if (localCpr.hasExternalProcessHandles()) {
7866                if (localCpr.removeExternalProcessHandleLocked(token)) {
7867                    updateOomAdjLocked();
7868                } else {
7869                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
7870                            + " with no external reference for token: "
7871                            + token + ".");
7872                }
7873            } else {
7874                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
7875                        + " with no external references.");
7876            }
7877        }
7878    }
7879
7880    public final void publishContentProviders(IApplicationThread caller,
7881            List<ContentProviderHolder> providers) {
7882        if (providers == null) {
7883            return;
7884        }
7885
7886        enforceNotIsolatedCaller("publishContentProviders");
7887        synchronized (this) {
7888            final ProcessRecord r = getRecordForAppLocked(caller);
7889            if (DEBUG_MU)
7890                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
7891            if (r == null) {
7892                throw new SecurityException(
7893                        "Unable to find app for caller " + caller
7894                      + " (pid=" + Binder.getCallingPid()
7895                      + ") when publishing content providers");
7896            }
7897
7898            final long origId = Binder.clearCallingIdentity();
7899
7900            final int N = providers.size();
7901            for (int i=0; i<N; i++) {
7902                ContentProviderHolder src = providers.get(i);
7903                if (src == null || src.info == null || src.provider == null) {
7904                    continue;
7905                }
7906                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
7907                if (DEBUG_MU)
7908                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
7909                if (dst != null) {
7910                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
7911                    mProviderMap.putProviderByClass(comp, dst);
7912                    String names[] = dst.info.authority.split(";");
7913                    for (int j = 0; j < names.length; j++) {
7914                        mProviderMap.putProviderByName(names[j], dst);
7915                    }
7916
7917                    int NL = mLaunchingProviders.size();
7918                    int j;
7919                    for (j=0; j<NL; j++) {
7920                        if (mLaunchingProviders.get(j) == dst) {
7921                            mLaunchingProviders.remove(j);
7922                            j--;
7923                            NL--;
7924                        }
7925                    }
7926                    synchronized (dst) {
7927                        dst.provider = src.provider;
7928                        dst.proc = r;
7929                        dst.notifyAll();
7930                    }
7931                    updateOomAdjLocked(r);
7932                }
7933            }
7934
7935            Binder.restoreCallingIdentity(origId);
7936        }
7937    }
7938
7939    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
7940        ContentProviderConnection conn;
7941        try {
7942            conn = (ContentProviderConnection)connection;
7943        } catch (ClassCastException e) {
7944            String msg ="refContentProvider: " + connection
7945                    + " not a ContentProviderConnection";
7946            Slog.w(TAG, msg);
7947            throw new IllegalArgumentException(msg);
7948        }
7949        if (conn == null) {
7950            throw new NullPointerException("connection is null");
7951        }
7952
7953        synchronized (this) {
7954            if (stable > 0) {
7955                conn.numStableIncs += stable;
7956            }
7957            stable = conn.stableCount + stable;
7958            if (stable < 0) {
7959                throw new IllegalStateException("stableCount < 0: " + stable);
7960            }
7961
7962            if (unstable > 0) {
7963                conn.numUnstableIncs += unstable;
7964            }
7965            unstable = conn.unstableCount + unstable;
7966            if (unstable < 0) {
7967                throw new IllegalStateException("unstableCount < 0: " + unstable);
7968            }
7969
7970            if ((stable+unstable) <= 0) {
7971                throw new IllegalStateException("ref counts can't go to zero here: stable="
7972                        + stable + " unstable=" + unstable);
7973            }
7974            conn.stableCount = stable;
7975            conn.unstableCount = unstable;
7976            return !conn.dead;
7977        }
7978    }
7979
7980    public void unstableProviderDied(IBinder connection) {
7981        ContentProviderConnection conn;
7982        try {
7983            conn = (ContentProviderConnection)connection;
7984        } catch (ClassCastException e) {
7985            String msg ="refContentProvider: " + connection
7986                    + " not a ContentProviderConnection";
7987            Slog.w(TAG, msg);
7988            throw new IllegalArgumentException(msg);
7989        }
7990        if (conn == null) {
7991            throw new NullPointerException("connection is null");
7992        }
7993
7994        // Safely retrieve the content provider associated with the connection.
7995        IContentProvider provider;
7996        synchronized (this) {
7997            provider = conn.provider.provider;
7998        }
7999
8000        if (provider == null) {
8001            // Um, yeah, we're way ahead of you.
8002            return;
8003        }
8004
8005        // Make sure the caller is being honest with us.
8006        if (provider.asBinder().pingBinder()) {
8007            // Er, no, still looks good to us.
8008            synchronized (this) {
8009                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8010                        + " says " + conn + " died, but we don't agree");
8011                return;
8012            }
8013        }
8014
8015        // Well look at that!  It's dead!
8016        synchronized (this) {
8017            if (conn.provider.provider != provider) {
8018                // But something changed...  good enough.
8019                return;
8020            }
8021
8022            ProcessRecord proc = conn.provider.proc;
8023            if (proc == null || proc.thread == null) {
8024                // Seems like the process is already cleaned up.
8025                return;
8026            }
8027
8028            // As far as we're concerned, this is just like receiving a
8029            // death notification...  just a bit prematurely.
8030            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8031                    + ") early provider death");
8032            final long ident = Binder.clearCallingIdentity();
8033            try {
8034                appDiedLocked(proc, proc.pid, proc.thread);
8035            } finally {
8036                Binder.restoreCallingIdentity(ident);
8037            }
8038        }
8039    }
8040
8041    @Override
8042    public void appNotRespondingViaProvider(IBinder connection) {
8043        enforceCallingPermission(
8044                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8045
8046        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8047        if (conn == null) {
8048            Slog.w(TAG, "ContentProviderConnection is null");
8049            return;
8050        }
8051
8052        final ProcessRecord host = conn.provider.proc;
8053        if (host == null) {
8054            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8055            return;
8056        }
8057
8058        final long token = Binder.clearCallingIdentity();
8059        try {
8060            appNotResponding(host, null, null, false, "ContentProvider not responding");
8061        } finally {
8062            Binder.restoreCallingIdentity(token);
8063        }
8064    }
8065
8066    public final void installSystemProviders() {
8067        List<ProviderInfo> providers;
8068        synchronized (this) {
8069            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8070            providers = generateApplicationProvidersLocked(app);
8071            if (providers != null) {
8072                for (int i=providers.size()-1; i>=0; i--) {
8073                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8074                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8075                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8076                                + ": not system .apk");
8077                        providers.remove(i);
8078                    }
8079                }
8080            }
8081        }
8082        if (providers != null) {
8083            mSystemThread.installSystemProviders(providers);
8084        }
8085
8086        mCoreSettingsObserver = new CoreSettingsObserver(this);
8087
8088        mUsageStatsService.monitorPackages();
8089    }
8090
8091    /**
8092     * Allows app to retrieve the MIME type of a URI without having permission
8093     * to access its content provider.
8094     *
8095     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8096     *
8097     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8098     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8099     */
8100    public String getProviderMimeType(Uri uri, int userId) {
8101        enforceNotIsolatedCaller("getProviderMimeType");
8102        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8103                userId, false, true, "getProviderMimeType", null);
8104        final String name = uri.getAuthority();
8105        final long ident = Binder.clearCallingIdentity();
8106        ContentProviderHolder holder = null;
8107
8108        try {
8109            holder = getContentProviderExternalUnchecked(name, null, userId);
8110            if (holder != null) {
8111                return holder.provider.getType(uri);
8112            }
8113        } catch (RemoteException e) {
8114            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8115            return null;
8116        } finally {
8117            if (holder != null) {
8118                removeContentProviderExternalUnchecked(name, null, userId);
8119            }
8120            Binder.restoreCallingIdentity(ident);
8121        }
8122
8123        return null;
8124    }
8125
8126    // =========================================================
8127    // GLOBAL MANAGEMENT
8128    // =========================================================
8129
8130    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8131            boolean isolated) {
8132        String proc = customProcess != null ? customProcess : info.processName;
8133        BatteryStatsImpl.Uid.Proc ps = null;
8134        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8135        int uid = info.uid;
8136        if (isolated) {
8137            int userId = UserHandle.getUserId(uid);
8138            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8139            while (true) {
8140                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8141                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8142                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8143                }
8144                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8145                mNextIsolatedProcessUid++;
8146                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8147                    // No process for this uid, use it.
8148                    break;
8149                }
8150                stepsLeft--;
8151                if (stepsLeft <= 0) {
8152                    return null;
8153                }
8154            }
8155        }
8156        return new ProcessRecord(stats, info, proc, uid);
8157    }
8158
8159    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
8160        ProcessRecord app;
8161        if (!isolated) {
8162            app = getProcessRecordLocked(info.processName, info.uid, true);
8163        } else {
8164            app = null;
8165        }
8166
8167        if (app == null) {
8168            app = newProcessRecordLocked(info, null, isolated);
8169            mProcessNames.put(info.processName, app.uid, app);
8170            if (isolated) {
8171                mIsolatedProcesses.put(app.uid, app);
8172            }
8173            updateLruProcessLocked(app, false, null);
8174            updateOomAdjLocked();
8175        }
8176
8177        // This package really, really can not be stopped.
8178        try {
8179            AppGlobals.getPackageManager().setPackageStoppedState(
8180                    info.packageName, false, UserHandle.getUserId(app.uid));
8181        } catch (RemoteException e) {
8182        } catch (IllegalArgumentException e) {
8183            Slog.w(TAG, "Failed trying to unstop package "
8184                    + info.packageName + ": " + e);
8185        }
8186
8187        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8188                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8189            app.persistent = true;
8190            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8191        }
8192        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8193            mPersistentStartingProcesses.add(app);
8194            startProcessLocked(app, "added application", app.processName);
8195        }
8196
8197        return app;
8198    }
8199
8200    public void unhandledBack() {
8201        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8202                "unhandledBack()");
8203
8204        synchronized(this) {
8205            final long origId = Binder.clearCallingIdentity();
8206            try {
8207                getFocusedStack().unhandledBackLocked();
8208            } finally {
8209                Binder.restoreCallingIdentity(origId);
8210            }
8211        }
8212    }
8213
8214    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8215        enforceNotIsolatedCaller("openContentUri");
8216        final int userId = UserHandle.getCallingUserId();
8217        String name = uri.getAuthority();
8218        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8219        ParcelFileDescriptor pfd = null;
8220        if (cph != null) {
8221            // We record the binder invoker's uid in thread-local storage before
8222            // going to the content provider to open the file.  Later, in the code
8223            // that handles all permissions checks, we look for this uid and use
8224            // that rather than the Activity Manager's own uid.  The effect is that
8225            // we do the check against the caller's permissions even though it looks
8226            // to the content provider like the Activity Manager itself is making
8227            // the request.
8228            sCallerIdentity.set(new Identity(
8229                    Binder.getCallingPid(), Binder.getCallingUid()));
8230            try {
8231                pfd = cph.provider.openFile(null, uri, "r", null);
8232            } catch (FileNotFoundException e) {
8233                // do nothing; pfd will be returned null
8234            } finally {
8235                // Ensure that whatever happens, we clean up the identity state
8236                sCallerIdentity.remove();
8237            }
8238
8239            // We've got the fd now, so we're done with the provider.
8240            removeContentProviderExternalUnchecked(name, null, userId);
8241        } else {
8242            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8243        }
8244        return pfd;
8245    }
8246
8247    // Actually is sleeping or shutting down or whatever else in the future
8248    // is an inactive state.
8249    public boolean isSleepingOrShuttingDown() {
8250        return mSleeping || mShuttingDown;
8251    }
8252
8253    public void goingToSleep() {
8254        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8255                != PackageManager.PERMISSION_GRANTED) {
8256            throw new SecurityException("Requires permission "
8257                    + android.Manifest.permission.DEVICE_POWER);
8258        }
8259
8260        synchronized(this) {
8261            mWentToSleep = true;
8262            updateEventDispatchingLocked();
8263
8264            if (!mSleeping) {
8265                mSleeping = true;
8266                mStackSupervisor.goingToSleepLocked();
8267
8268                // Initialize the wake times of all processes.
8269                checkExcessivePowerUsageLocked(false);
8270                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8271                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8272                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8273            }
8274        }
8275    }
8276
8277    @Override
8278    public boolean shutdown(int timeout) {
8279        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8280                != PackageManager.PERMISSION_GRANTED) {
8281            throw new SecurityException("Requires permission "
8282                    + android.Manifest.permission.SHUTDOWN);
8283        }
8284
8285        boolean timedout = false;
8286
8287        synchronized(this) {
8288            mShuttingDown = true;
8289            updateEventDispatchingLocked();
8290            timedout = mStackSupervisor.shutdownLocked(timeout);
8291        }
8292
8293        mAppOpsService.shutdown();
8294        mUsageStatsService.shutdown();
8295        mBatteryStatsService.shutdown();
8296        synchronized (this) {
8297            mProcessStats.shutdownLocked();
8298        }
8299
8300        return timedout;
8301    }
8302
8303    public final void activitySlept(IBinder token) {
8304        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8305
8306        final long origId = Binder.clearCallingIdentity();
8307
8308        synchronized (this) {
8309            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8310            if (r != null) {
8311                mStackSupervisor.activitySleptLocked(r);
8312            }
8313        }
8314
8315        Binder.restoreCallingIdentity(origId);
8316    }
8317
8318    void logLockScreen(String msg) {
8319        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8320                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8321                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8322                mStackSupervisor.mDismissKeyguardOnNextActivity);
8323    }
8324
8325    private void comeOutOfSleepIfNeededLocked() {
8326        if (!mWentToSleep && !mLockScreenShown) {
8327            if (mSleeping) {
8328                mSleeping = false;
8329                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8330            }
8331        }
8332    }
8333
8334    public void wakingUp() {
8335        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8336                != PackageManager.PERMISSION_GRANTED) {
8337            throw new SecurityException("Requires permission "
8338                    + android.Manifest.permission.DEVICE_POWER);
8339        }
8340
8341        synchronized(this) {
8342            mWentToSleep = false;
8343            updateEventDispatchingLocked();
8344            comeOutOfSleepIfNeededLocked();
8345        }
8346    }
8347
8348    private void updateEventDispatchingLocked() {
8349        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8350    }
8351
8352    public void setLockScreenShown(boolean shown) {
8353        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8354                != PackageManager.PERMISSION_GRANTED) {
8355            throw new SecurityException("Requires permission "
8356                    + android.Manifest.permission.DEVICE_POWER);
8357        }
8358
8359        synchronized(this) {
8360            long ident = Binder.clearCallingIdentity();
8361            try {
8362                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8363                mLockScreenShown = shown;
8364                comeOutOfSleepIfNeededLocked();
8365            } finally {
8366                Binder.restoreCallingIdentity(ident);
8367            }
8368        }
8369    }
8370
8371    public void stopAppSwitches() {
8372        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8373                != PackageManager.PERMISSION_GRANTED) {
8374            throw new SecurityException("Requires permission "
8375                    + android.Manifest.permission.STOP_APP_SWITCHES);
8376        }
8377
8378        synchronized(this) {
8379            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8380                    + APP_SWITCH_DELAY_TIME;
8381            mDidAppSwitch = false;
8382            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8383            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8384            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8385        }
8386    }
8387
8388    public void resumeAppSwitches() {
8389        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8390                != PackageManager.PERMISSION_GRANTED) {
8391            throw new SecurityException("Requires permission "
8392                    + android.Manifest.permission.STOP_APP_SWITCHES);
8393        }
8394
8395        synchronized(this) {
8396            // Note that we don't execute any pending app switches... we will
8397            // let those wait until either the timeout, or the next start
8398            // activity request.
8399            mAppSwitchesAllowedTime = 0;
8400        }
8401    }
8402
8403    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
8404            String name) {
8405        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
8406            return true;
8407        }
8408
8409        final int perm = checkComponentPermission(
8410                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
8411                callingUid, -1, true);
8412        if (perm == PackageManager.PERMISSION_GRANTED) {
8413            return true;
8414        }
8415
8416        Slog.w(TAG, name + " request from " + callingUid + " stopped");
8417        return false;
8418    }
8419
8420    public void setDebugApp(String packageName, boolean waitForDebugger,
8421            boolean persistent) {
8422        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
8423                "setDebugApp()");
8424
8425        long ident = Binder.clearCallingIdentity();
8426        try {
8427            // Note that this is not really thread safe if there are multiple
8428            // callers into it at the same time, but that's not a situation we
8429            // care about.
8430            if (persistent) {
8431                final ContentResolver resolver = mContext.getContentResolver();
8432                Settings.Global.putString(
8433                    resolver, Settings.Global.DEBUG_APP,
8434                    packageName);
8435                Settings.Global.putInt(
8436                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
8437                    waitForDebugger ? 1 : 0);
8438            }
8439
8440            synchronized (this) {
8441                if (!persistent) {
8442                    mOrigDebugApp = mDebugApp;
8443                    mOrigWaitForDebugger = mWaitForDebugger;
8444                }
8445                mDebugApp = packageName;
8446                mWaitForDebugger = waitForDebugger;
8447                mDebugTransient = !persistent;
8448                if (packageName != null) {
8449                    forceStopPackageLocked(packageName, -1, false, false, true, true,
8450                            false, UserHandle.USER_ALL, "set debug app");
8451                }
8452            }
8453        } finally {
8454            Binder.restoreCallingIdentity(ident);
8455        }
8456    }
8457
8458    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
8459        synchronized (this) {
8460            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8461            if (!isDebuggable) {
8462                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8463                    throw new SecurityException("Process not debuggable: " + app.packageName);
8464                }
8465            }
8466
8467            mOpenGlTraceApp = processName;
8468        }
8469    }
8470
8471    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
8472            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
8473        synchronized (this) {
8474            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
8475            if (!isDebuggable) {
8476                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
8477                    throw new SecurityException("Process not debuggable: " + app.packageName);
8478                }
8479            }
8480            mProfileApp = processName;
8481            mProfileFile = profileFile;
8482            if (mProfileFd != null) {
8483                try {
8484                    mProfileFd.close();
8485                } catch (IOException e) {
8486                }
8487                mProfileFd = null;
8488            }
8489            mProfileFd = profileFd;
8490            mProfileType = 0;
8491            mAutoStopProfiler = autoStopProfiler;
8492        }
8493    }
8494
8495    @Override
8496    public void setAlwaysFinish(boolean enabled) {
8497        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
8498                "setAlwaysFinish()");
8499
8500        Settings.Global.putInt(
8501                mContext.getContentResolver(),
8502                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
8503
8504        synchronized (this) {
8505            mAlwaysFinishActivities = enabled;
8506        }
8507    }
8508
8509    @Override
8510    public void setActivityController(IActivityController controller) {
8511        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8512                "setActivityController()");
8513        synchronized (this) {
8514            mController = controller;
8515            Watchdog.getInstance().setActivityController(controller);
8516        }
8517    }
8518
8519    @Override
8520    public void setUserIsMonkey(boolean userIsMonkey) {
8521        synchronized (this) {
8522            synchronized (mPidsSelfLocked) {
8523                final int callingPid = Binder.getCallingPid();
8524                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
8525                if (precessRecord == null) {
8526                    throw new SecurityException("Unknown process: " + callingPid);
8527                }
8528                if (precessRecord.instrumentationUiAutomationConnection  == null) {
8529                    throw new SecurityException("Only an instrumentation process "
8530                            + "with a UiAutomation can call setUserIsMonkey");
8531                }
8532            }
8533            mUserIsMonkey = userIsMonkey;
8534        }
8535    }
8536
8537    @Override
8538    public boolean isUserAMonkey() {
8539        synchronized (this) {
8540            // If there is a controller also implies the user is a monkey.
8541            return (mUserIsMonkey || mController != null);
8542        }
8543    }
8544
8545    public void requestBugReport() {
8546        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
8547        SystemProperties.set("ctl.start", "bugreport");
8548    }
8549
8550    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
8551        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
8552    }
8553
8554    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
8555        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
8556            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
8557        }
8558        return KEY_DISPATCHING_TIMEOUT;
8559    }
8560
8561    @Override
8562    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
8563        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8564                != PackageManager.PERMISSION_GRANTED) {
8565            throw new SecurityException("Requires permission "
8566                    + android.Manifest.permission.FILTER_EVENTS);
8567        }
8568        ProcessRecord proc;
8569        long timeout;
8570        synchronized (this) {
8571            synchronized (mPidsSelfLocked) {
8572                proc = mPidsSelfLocked.get(pid);
8573            }
8574            timeout = getInputDispatchingTimeoutLocked(proc);
8575        }
8576
8577        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
8578            return -1;
8579        }
8580
8581        return timeout;
8582    }
8583
8584    /**
8585     * Handle input dispatching timeouts.
8586     * Returns whether input dispatching should be aborted or not.
8587     */
8588    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
8589            final ActivityRecord activity, final ActivityRecord parent,
8590            final boolean aboveSystem, String reason) {
8591        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
8592                != PackageManager.PERMISSION_GRANTED) {
8593            throw new SecurityException("Requires permission "
8594                    + android.Manifest.permission.FILTER_EVENTS);
8595        }
8596
8597        final String annotation;
8598        if (reason == null) {
8599            annotation = "Input dispatching timed out";
8600        } else {
8601            annotation = "Input dispatching timed out (" + reason + ")";
8602        }
8603
8604        if (proc != null) {
8605            synchronized (this) {
8606                if (proc.debugging) {
8607                    return false;
8608                }
8609
8610                if (mDidDexOpt) {
8611                    // Give more time since we were dexopting.
8612                    mDidDexOpt = false;
8613                    return false;
8614                }
8615
8616                if (proc.instrumentationClass != null) {
8617                    Bundle info = new Bundle();
8618                    info.putString("shortMsg", "keyDispatchingTimedOut");
8619                    info.putString("longMsg", annotation);
8620                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
8621                    return true;
8622                }
8623            }
8624            mHandler.post(new Runnable() {
8625                @Override
8626                public void run() {
8627                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
8628                }
8629            });
8630        }
8631
8632        return true;
8633    }
8634
8635    public Bundle getAssistContextExtras(int requestType) {
8636        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
8637                "getAssistContextExtras()");
8638        PendingAssistExtras pae;
8639        Bundle extras = new Bundle();
8640        synchronized (this) {
8641            ActivityRecord activity = getFocusedStack().mResumedActivity;
8642            if (activity == null) {
8643                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
8644                return null;
8645            }
8646            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
8647            if (activity.app == null || activity.app.thread == null) {
8648                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
8649                return extras;
8650            }
8651            if (activity.app.pid == Binder.getCallingPid()) {
8652                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
8653                return extras;
8654            }
8655            pae = new PendingAssistExtras(activity);
8656            try {
8657                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
8658                        requestType);
8659                mPendingAssistExtras.add(pae);
8660                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
8661            } catch (RemoteException e) {
8662                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
8663                return extras;
8664            }
8665        }
8666        synchronized (pae) {
8667            while (!pae.haveResult) {
8668                try {
8669                    pae.wait();
8670                } catch (InterruptedException e) {
8671                }
8672            }
8673            if (pae.result != null) {
8674                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
8675            }
8676        }
8677        synchronized (this) {
8678            mPendingAssistExtras.remove(pae);
8679            mHandler.removeCallbacks(pae);
8680        }
8681        return extras;
8682    }
8683
8684    public void reportAssistContextExtras(IBinder token, Bundle extras) {
8685        PendingAssistExtras pae = (PendingAssistExtras)token;
8686        synchronized (pae) {
8687            pae.result = extras;
8688            pae.haveResult = true;
8689            pae.notifyAll();
8690        }
8691    }
8692
8693    public void registerProcessObserver(IProcessObserver observer) {
8694        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
8695                "registerProcessObserver()");
8696        synchronized (this) {
8697            mProcessObservers.register(observer);
8698        }
8699    }
8700
8701    @Override
8702    public void unregisterProcessObserver(IProcessObserver observer) {
8703        synchronized (this) {
8704            mProcessObservers.unregister(observer);
8705        }
8706    }
8707
8708    @Override
8709    public boolean convertFromTranslucent(IBinder token) {
8710        final long origId = Binder.clearCallingIdentity();
8711        try {
8712            synchronized (this) {
8713                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8714                if (r == null) {
8715                    return false;
8716                }
8717                if (r.changeWindowTranslucency(true)) {
8718                    mWindowManager.setAppFullscreen(token, true);
8719                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8720                    return true;
8721                }
8722                return false;
8723            }
8724        } finally {
8725            Binder.restoreCallingIdentity(origId);
8726        }
8727    }
8728
8729    @Override
8730    public boolean convertToTranslucent(IBinder token) {
8731        final long origId = Binder.clearCallingIdentity();
8732        try {
8733            synchronized (this) {
8734                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8735                if (r == null) {
8736                    return false;
8737                }
8738                if (r.changeWindowTranslucency(false)) {
8739                    r.task.stack.convertToTranslucent(r);
8740                    mWindowManager.setAppFullscreen(token, false);
8741                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8742                    return true;
8743                }
8744                return false;
8745            }
8746        } finally {
8747            Binder.restoreCallingIdentity(origId);
8748        }
8749    }
8750
8751    @Override
8752    public void setImmersive(IBinder token, boolean immersive) {
8753        synchronized(this) {
8754            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8755            if (r == null) {
8756                throw new IllegalArgumentException();
8757            }
8758            r.immersive = immersive;
8759
8760            // update associated state if we're frontmost
8761            if (r == mFocusedActivity) {
8762                if (DEBUG_IMMERSIVE) {
8763                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
8764                }
8765                applyUpdateLockStateLocked(r);
8766            }
8767        }
8768    }
8769
8770    @Override
8771    public boolean isImmersive(IBinder token) {
8772        synchronized (this) {
8773            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8774            if (r == null) {
8775                throw new IllegalArgumentException();
8776            }
8777            return r.immersive;
8778        }
8779    }
8780
8781    public boolean isTopActivityImmersive() {
8782        enforceNotIsolatedCaller("startActivity");
8783        synchronized (this) {
8784            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
8785            return (r != null) ? r.immersive : false;
8786        }
8787    }
8788
8789    public final void enterSafeMode() {
8790        synchronized(this) {
8791            // It only makes sense to do this before the system is ready
8792            // and started launching other packages.
8793            if (!mSystemReady) {
8794                try {
8795                    AppGlobals.getPackageManager().enterSafeMode();
8796                } catch (RemoteException e) {
8797                }
8798            }
8799        }
8800    }
8801
8802    public final void showSafeModeOverlay() {
8803        View v = LayoutInflater.from(mContext).inflate(
8804                com.android.internal.R.layout.safe_mode, null);
8805        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
8806        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
8807        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
8808        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
8809        lp.gravity = Gravity.BOTTOM | Gravity.START;
8810        lp.format = v.getBackground().getOpacity();
8811        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
8812                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
8813        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
8814        ((WindowManager)mContext.getSystemService(
8815                Context.WINDOW_SERVICE)).addView(v, lp);
8816    }
8817
8818    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
8819        if (!(sender instanceof PendingIntentRecord)) {
8820            return;
8821        }
8822        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8823        synchronized (stats) {
8824            if (mBatteryStatsService.isOnBattery()) {
8825                mBatteryStatsService.enforceCallingPermission();
8826                PendingIntentRecord rec = (PendingIntentRecord)sender;
8827                int MY_UID = Binder.getCallingUid();
8828                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
8829                BatteryStatsImpl.Uid.Pkg pkg =
8830                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
8831                            sourcePkg != null ? sourcePkg : rec.key.packageName);
8832                pkg.incWakeupsLocked();
8833            }
8834        }
8835    }
8836
8837    public boolean killPids(int[] pids, String pReason, boolean secure) {
8838        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8839            throw new SecurityException("killPids only available to the system");
8840        }
8841        String reason = (pReason == null) ? "Unknown" : pReason;
8842        // XXX Note: don't acquire main activity lock here, because the window
8843        // manager calls in with its locks held.
8844
8845        boolean killed = false;
8846        synchronized (mPidsSelfLocked) {
8847            int[] types = new int[pids.length];
8848            int worstType = 0;
8849            for (int i=0; i<pids.length; i++) {
8850                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8851                if (proc != null) {
8852                    int type = proc.setAdj;
8853                    types[i] = type;
8854                    if (type > worstType) {
8855                        worstType = type;
8856                    }
8857                }
8858            }
8859
8860            // If the worst oom_adj is somewhere in the cached proc LRU range,
8861            // then constrain it so we will kill all cached procs.
8862            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
8863                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
8864                worstType = ProcessList.CACHED_APP_MIN_ADJ;
8865            }
8866
8867            // If this is not a secure call, don't let it kill processes that
8868            // are important.
8869            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
8870                worstType = ProcessList.SERVICE_ADJ;
8871            }
8872
8873            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
8874            for (int i=0; i<pids.length; i++) {
8875                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
8876                if (proc == null) {
8877                    continue;
8878                }
8879                int adj = proc.setAdj;
8880                if (adj >= worstType && !proc.killedByAm) {
8881                    killUnneededProcessLocked(proc, reason);
8882                    killed = true;
8883                }
8884            }
8885        }
8886        return killed;
8887    }
8888
8889    @Override
8890    public void killUid(int uid, String reason) {
8891        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8892            throw new SecurityException("killUid only available to the system");
8893        }
8894        synchronized (this) {
8895            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
8896                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
8897                    reason != null ? reason : "kill uid");
8898        }
8899    }
8900
8901    @Override
8902    public boolean killProcessesBelowForeground(String reason) {
8903        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8904            throw new SecurityException("killProcessesBelowForeground() only available to system");
8905        }
8906
8907        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
8908    }
8909
8910    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
8911        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8912            throw new SecurityException("killProcessesBelowAdj() only available to system");
8913        }
8914
8915        boolean killed = false;
8916        synchronized (mPidsSelfLocked) {
8917            final int size = mPidsSelfLocked.size();
8918            for (int i = 0; i < size; i++) {
8919                final int pid = mPidsSelfLocked.keyAt(i);
8920                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
8921                if (proc == null) continue;
8922
8923                final int adj = proc.setAdj;
8924                if (adj > belowAdj && !proc.killedByAm) {
8925                    killUnneededProcessLocked(proc, reason);
8926                    killed = true;
8927                }
8928            }
8929        }
8930        return killed;
8931    }
8932
8933    @Override
8934    public void hang(final IBinder who, boolean allowRestart) {
8935        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8936                != PackageManager.PERMISSION_GRANTED) {
8937            throw new SecurityException("Requires permission "
8938                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8939        }
8940
8941        final IBinder.DeathRecipient death = new DeathRecipient() {
8942            @Override
8943            public void binderDied() {
8944                synchronized (this) {
8945                    notifyAll();
8946                }
8947            }
8948        };
8949
8950        try {
8951            who.linkToDeath(death, 0);
8952        } catch (RemoteException e) {
8953            Slog.w(TAG, "hang: given caller IBinder is already dead.");
8954            return;
8955        }
8956
8957        synchronized (this) {
8958            Watchdog.getInstance().setAllowRestart(allowRestart);
8959            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
8960            synchronized (death) {
8961                while (who.isBinderAlive()) {
8962                    try {
8963                        death.wait();
8964                    } catch (InterruptedException e) {
8965                    }
8966                }
8967            }
8968            Watchdog.getInstance().setAllowRestart(true);
8969        }
8970    }
8971
8972    @Override
8973    public void restart() {
8974        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
8975                != PackageManager.PERMISSION_GRANTED) {
8976            throw new SecurityException("Requires permission "
8977                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
8978        }
8979
8980        Log.i(TAG, "Sending shutdown broadcast...");
8981
8982        BroadcastReceiver br = new BroadcastReceiver() {
8983            @Override public void onReceive(Context context, Intent intent) {
8984                // Now the broadcast is done, finish up the low-level shutdown.
8985                Log.i(TAG, "Shutting down activity manager...");
8986                shutdown(10000);
8987                Log.i(TAG, "Shutdown complete, restarting!");
8988                Process.killProcess(Process.myPid());
8989                System.exit(10);
8990            }
8991        };
8992
8993        // First send the high-level shut down broadcast.
8994        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
8995        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
8996        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
8997        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
8998        mContext.sendOrderedBroadcastAsUser(intent,
8999                UserHandle.ALL, null, br, mHandler, 0, null, null);
9000        */
9001        br.onReceive(mContext, intent);
9002    }
9003
9004    private long getLowRamTimeSinceIdle(long now) {
9005        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9006    }
9007
9008    @Override
9009    public void performIdleMaintenance() {
9010        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9011                != PackageManager.PERMISSION_GRANTED) {
9012            throw new SecurityException("Requires permission "
9013                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9014        }
9015
9016        synchronized (this) {
9017            final long now = SystemClock.uptimeMillis();
9018            final long timeSinceLastIdle = now - mLastIdleTime;
9019            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9020            mLastIdleTime = now;
9021            mLowRamTimeSinceLastIdle = 0;
9022            if (mLowRamStartTime != 0) {
9023                mLowRamStartTime = now;
9024            }
9025
9026            StringBuilder sb = new StringBuilder(128);
9027            sb.append("Idle maintenance over ");
9028            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9029            sb.append(" low RAM for ");
9030            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9031            Slog.i(TAG, sb.toString());
9032
9033            // If at least 1/3 of our time since the last idle period has been spent
9034            // with RAM low, then we want to kill processes.
9035            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9036
9037            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9038                ProcessRecord proc = mLruProcesses.get(i);
9039                if (proc.notCachedSinceIdle) {
9040                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9041                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9042                        if (doKilling && proc.initialIdlePss != 0
9043                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9044                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9045                                    + " from " + proc.initialIdlePss + ")");
9046                        }
9047                    }
9048                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9049                    proc.notCachedSinceIdle = true;
9050                    proc.initialIdlePss = 0;
9051                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9052                            mSleeping, now);
9053                }
9054            }
9055
9056            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9057            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9058        }
9059    }
9060
9061    public final void startRunning(String pkg, String cls, String action,
9062            String data) {
9063        synchronized(this) {
9064            if (mStartRunning) {
9065                return;
9066            }
9067            mStartRunning = true;
9068            mTopComponent = pkg != null && cls != null
9069                    ? new ComponentName(pkg, cls) : null;
9070            mTopAction = action != null ? action : Intent.ACTION_MAIN;
9071            mTopData = data;
9072            if (!mSystemReady) {
9073                return;
9074            }
9075        }
9076
9077        systemReady(null);
9078    }
9079
9080    private void retrieveSettings() {
9081        final ContentResolver resolver = mContext.getContentResolver();
9082        String debugApp = Settings.Global.getString(
9083            resolver, Settings.Global.DEBUG_APP);
9084        boolean waitForDebugger = Settings.Global.getInt(
9085            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9086        boolean alwaysFinishActivities = Settings.Global.getInt(
9087            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9088        boolean forceRtl = Settings.Global.getInt(
9089                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9090        // Transfer any global setting for forcing RTL layout, into a System Property
9091        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9092
9093        Configuration configuration = new Configuration();
9094        Settings.System.getConfiguration(resolver, configuration);
9095        if (forceRtl) {
9096            // This will take care of setting the correct layout direction flags
9097            configuration.setLayoutDirection(configuration.locale);
9098        }
9099
9100        synchronized (this) {
9101            mDebugApp = mOrigDebugApp = debugApp;
9102            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9103            mAlwaysFinishActivities = alwaysFinishActivities;
9104            // This happens before any activities are started, so we can
9105            // change mConfiguration in-place.
9106            updateConfigurationLocked(configuration, null, false, true);
9107            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9108        }
9109    }
9110
9111    public boolean testIsSystemReady() {
9112        // no need to synchronize(this) just to read & return the value
9113        return mSystemReady;
9114    }
9115
9116    private static File getCalledPreBootReceiversFile() {
9117        File dataDir = Environment.getDataDirectory();
9118        File systemDir = new File(dataDir, "system");
9119        File fname = new File(systemDir, "called_pre_boots.dat");
9120        return fname;
9121    }
9122
9123    static final int LAST_DONE_VERSION = 10000;
9124
9125    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9126        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9127        File file = getCalledPreBootReceiversFile();
9128        FileInputStream fis = null;
9129        try {
9130            fis = new FileInputStream(file);
9131            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9132            int fvers = dis.readInt();
9133            if (fvers == LAST_DONE_VERSION) {
9134                String vers = dis.readUTF();
9135                String codename = dis.readUTF();
9136                String build = dis.readUTF();
9137                if (android.os.Build.VERSION.RELEASE.equals(vers)
9138                        && android.os.Build.VERSION.CODENAME.equals(codename)
9139                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9140                    int num = dis.readInt();
9141                    while (num > 0) {
9142                        num--;
9143                        String pkg = dis.readUTF();
9144                        String cls = dis.readUTF();
9145                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9146                    }
9147                }
9148            }
9149        } catch (FileNotFoundException e) {
9150        } catch (IOException e) {
9151            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9152        } finally {
9153            if (fis != null) {
9154                try {
9155                    fis.close();
9156                } catch (IOException e) {
9157                }
9158            }
9159        }
9160        return lastDoneReceivers;
9161    }
9162
9163    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9164        File file = getCalledPreBootReceiversFile();
9165        FileOutputStream fos = null;
9166        DataOutputStream dos = null;
9167        try {
9168            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9169            fos = new FileOutputStream(file);
9170            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9171            dos.writeInt(LAST_DONE_VERSION);
9172            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9173            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9174            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9175            dos.writeInt(list.size());
9176            for (int i=0; i<list.size(); i++) {
9177                dos.writeUTF(list.get(i).getPackageName());
9178                dos.writeUTF(list.get(i).getClassName());
9179            }
9180        } catch (IOException e) {
9181            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9182            file.delete();
9183        } finally {
9184            FileUtils.sync(fos);
9185            if (dos != null) {
9186                try {
9187                    dos.close();
9188                } catch (IOException e) {
9189                    // TODO Auto-generated catch block
9190                    e.printStackTrace();
9191                }
9192            }
9193        }
9194    }
9195
9196    public void systemReady(final Runnable goingCallback) {
9197        synchronized(this) {
9198            if (mSystemReady) {
9199                if (goingCallback != null) goingCallback.run();
9200                return;
9201            }
9202
9203            // Check to see if there are any update receivers to run.
9204            if (!mDidUpdate) {
9205                if (mWaitingUpdate) {
9206                    return;
9207                }
9208                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9209                List<ResolveInfo> ris = null;
9210                try {
9211                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9212                            intent, null, 0, 0);
9213                } catch (RemoteException e) {
9214                }
9215                if (ris != null) {
9216                    for (int i=ris.size()-1; i>=0; i--) {
9217                        if ((ris.get(i).activityInfo.applicationInfo.flags
9218                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9219                            ris.remove(i);
9220                        }
9221                    }
9222                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9223
9224                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9225
9226                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9227                    for (int i=0; i<ris.size(); i++) {
9228                        ActivityInfo ai = ris.get(i).activityInfo;
9229                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9230                        if (lastDoneReceivers.contains(comp)) {
9231                            ris.remove(i);
9232                            i--;
9233                        }
9234                    }
9235
9236                    final int[] users = getUsersLocked();
9237                    for (int i=0; i<ris.size(); i++) {
9238                        ActivityInfo ai = ris.get(i).activityInfo;
9239                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9240                        doneReceivers.add(comp);
9241                        intent.setComponent(comp);
9242                        for (int j=0; j<users.length; j++) {
9243                            IIntentReceiver finisher = null;
9244                            if (i == ris.size()-1 && j == users.length-1) {
9245                                finisher = new IIntentReceiver.Stub() {
9246                                    public void performReceive(Intent intent, int resultCode,
9247                                            String data, Bundle extras, boolean ordered,
9248                                            boolean sticky, int sendingUser) {
9249                                        // The raw IIntentReceiver interface is called
9250                                        // with the AM lock held, so redispatch to
9251                                        // execute our code without the lock.
9252                                        mHandler.post(new Runnable() {
9253                                            public void run() {
9254                                                synchronized (ActivityManagerService.this) {
9255                                                    mDidUpdate = true;
9256                                                }
9257                                                writeLastDonePreBootReceivers(doneReceivers);
9258                                                showBootMessage(mContext.getText(
9259                                                        R.string.android_upgrading_complete),
9260                                                        false);
9261                                                systemReady(goingCallback);
9262                                            }
9263                                        });
9264                                    }
9265                                };
9266                            }
9267                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9268                                    + " for user " + users[j]);
9269                            broadcastIntentLocked(null, null, intent, null, finisher,
9270                                    0, null, null, null, AppOpsManager.OP_NONE,
9271                                    true, false, MY_PID, Process.SYSTEM_UID,
9272                                    users[j]);
9273                            if (finisher != null) {
9274                                mWaitingUpdate = true;
9275                            }
9276                        }
9277                    }
9278                }
9279                if (mWaitingUpdate) {
9280                    return;
9281                }
9282                mDidUpdate = true;
9283            }
9284
9285            mAppOpsService.systemReady();
9286            mSystemReady = true;
9287            if (!mStartRunning) {
9288                return;
9289            }
9290        }
9291
9292        ArrayList<ProcessRecord> procsToKill = null;
9293        synchronized(mPidsSelfLocked) {
9294            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9295                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9296                if (!isAllowedWhileBooting(proc.info)){
9297                    if (procsToKill == null) {
9298                        procsToKill = new ArrayList<ProcessRecord>();
9299                    }
9300                    procsToKill.add(proc);
9301                }
9302            }
9303        }
9304
9305        synchronized(this) {
9306            if (procsToKill != null) {
9307                for (int i=procsToKill.size()-1; i>=0; i--) {
9308                    ProcessRecord proc = procsToKill.get(i);
9309                    Slog.i(TAG, "Removing system update proc: " + proc);
9310                    removeProcessLocked(proc, true, false, "system update done");
9311                }
9312            }
9313
9314            // Now that we have cleaned up any update processes, we
9315            // are ready to start launching real processes and know that
9316            // we won't trample on them any more.
9317            mProcessesReady = true;
9318        }
9319
9320        Slog.i(TAG, "System now ready");
9321        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9322            SystemClock.uptimeMillis());
9323
9324        synchronized(this) {
9325            // Make sure we have no pre-ready processes sitting around.
9326
9327            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9328                ResolveInfo ri = mContext.getPackageManager()
9329                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9330                                STOCK_PM_FLAGS);
9331                CharSequence errorMsg = null;
9332                if (ri != null) {
9333                    ActivityInfo ai = ri.activityInfo;
9334                    ApplicationInfo app = ai.applicationInfo;
9335                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9336                        mTopAction = Intent.ACTION_FACTORY_TEST;
9337                        mTopData = null;
9338                        mTopComponent = new ComponentName(app.packageName,
9339                                ai.name);
9340                    } else {
9341                        errorMsg = mContext.getResources().getText(
9342                                com.android.internal.R.string.factorytest_not_system);
9343                    }
9344                } else {
9345                    errorMsg = mContext.getResources().getText(
9346                            com.android.internal.R.string.factorytest_no_action);
9347                }
9348                if (errorMsg != null) {
9349                    mTopAction = null;
9350                    mTopData = null;
9351                    mTopComponent = null;
9352                    Message msg = Message.obtain();
9353                    msg.what = SHOW_FACTORY_ERROR_MSG;
9354                    msg.getData().putCharSequence("msg", errorMsg);
9355                    mHandler.sendMessage(msg);
9356                }
9357            }
9358        }
9359
9360        retrieveSettings();
9361
9362        synchronized (this) {
9363            readGrantedUriPermissionsLocked();
9364        }
9365
9366        if (goingCallback != null) goingCallback.run();
9367
9368        synchronized (this) {
9369            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9370                try {
9371                    List apps = AppGlobals.getPackageManager().
9372                        getPersistentApplications(STOCK_PM_FLAGS);
9373                    if (apps != null) {
9374                        int N = apps.size();
9375                        int i;
9376                        for (i=0; i<N; i++) {
9377                            ApplicationInfo info
9378                                = (ApplicationInfo)apps.get(i);
9379                            if (info != null &&
9380                                    !info.packageName.equals("android")) {
9381                                addAppLocked(info, false);
9382                            }
9383                        }
9384                    }
9385                } catch (RemoteException ex) {
9386                    // pm is in same process, this will never happen.
9387                }
9388            }
9389
9390            // Start up initial activity.
9391            mBooting = true;
9392
9393            try {
9394                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
9395                    Message msg = Message.obtain();
9396                    msg.what = SHOW_UID_ERROR_MSG;
9397                    mHandler.sendMessage(msg);
9398                }
9399            } catch (RemoteException e) {
9400            }
9401
9402            long ident = Binder.clearCallingIdentity();
9403            try {
9404                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
9405                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
9406                        | Intent.FLAG_RECEIVER_FOREGROUND);
9407                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9408                broadcastIntentLocked(null, null, intent,
9409                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
9410                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
9411                intent = new Intent(Intent.ACTION_USER_STARTING);
9412                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
9413                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
9414                broadcastIntentLocked(null, null, intent,
9415                        null, new IIntentReceiver.Stub() {
9416                            @Override
9417                            public void performReceive(Intent intent, int resultCode, String data,
9418                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
9419                                    throws RemoteException {
9420                            }
9421                        }, 0, null, null,
9422                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
9423                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
9424            } finally {
9425                Binder.restoreCallingIdentity(ident);
9426            }
9427            mStackSupervisor.resumeTopActivitiesLocked();
9428            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
9429        }
9430    }
9431
9432    private boolean makeAppCrashingLocked(ProcessRecord app,
9433            String shortMsg, String longMsg, String stackTrace) {
9434        app.crashing = true;
9435        app.crashingReport = generateProcessError(app,
9436                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
9437        startAppProblemLocked(app);
9438        app.stopFreezingAllLocked();
9439        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
9440    }
9441
9442    private void makeAppNotRespondingLocked(ProcessRecord app,
9443            String activity, String shortMsg, String longMsg) {
9444        app.notResponding = true;
9445        app.notRespondingReport = generateProcessError(app,
9446                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
9447                activity, shortMsg, longMsg, null);
9448        startAppProblemLocked(app);
9449        app.stopFreezingAllLocked();
9450    }
9451
9452    /**
9453     * Generate a process error record, suitable for attachment to a ProcessRecord.
9454     *
9455     * @param app The ProcessRecord in which the error occurred.
9456     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
9457     *                      ActivityManager.AppErrorStateInfo
9458     * @param activity The activity associated with the crash, if known.
9459     * @param shortMsg Short message describing the crash.
9460     * @param longMsg Long message describing the crash.
9461     * @param stackTrace Full crash stack trace, may be null.
9462     *
9463     * @return Returns a fully-formed AppErrorStateInfo record.
9464     */
9465    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
9466            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
9467        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
9468
9469        report.condition = condition;
9470        report.processName = app.processName;
9471        report.pid = app.pid;
9472        report.uid = app.info.uid;
9473        report.tag = activity;
9474        report.shortMsg = shortMsg;
9475        report.longMsg = longMsg;
9476        report.stackTrace = stackTrace;
9477
9478        return report;
9479    }
9480
9481    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
9482        synchronized (this) {
9483            app.crashing = false;
9484            app.crashingReport = null;
9485            app.notResponding = false;
9486            app.notRespondingReport = null;
9487            if (app.anrDialog == fromDialog) {
9488                app.anrDialog = null;
9489            }
9490            if (app.waitDialog == fromDialog) {
9491                app.waitDialog = null;
9492            }
9493            if (app.pid > 0 && app.pid != MY_PID) {
9494                handleAppCrashLocked(app, null, null, null);
9495                killUnneededProcessLocked(app, "user request after error");
9496            }
9497        }
9498    }
9499
9500    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
9501            String stackTrace) {
9502        long now = SystemClock.uptimeMillis();
9503
9504        Long crashTime;
9505        if (!app.isolated) {
9506            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
9507        } else {
9508            crashTime = null;
9509        }
9510        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
9511            // This process loses!
9512            Slog.w(TAG, "Process " + app.info.processName
9513                    + " has crashed too many times: killing!");
9514            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
9515                    app.userId, app.info.processName, app.uid);
9516            mStackSupervisor.handleAppCrashLocked(app);
9517            if (!app.persistent) {
9518                // We don't want to start this process again until the user
9519                // explicitly does so...  but for persistent process, we really
9520                // need to keep it running.  If a persistent process is actually
9521                // repeatedly crashing, then badness for everyone.
9522                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
9523                        app.info.processName);
9524                if (!app.isolated) {
9525                    // XXX We don't have a way to mark isolated processes
9526                    // as bad, since they don't have a peristent identity.
9527                    mBadProcesses.put(app.info.processName, app.uid,
9528                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
9529                    mProcessCrashTimes.remove(app.info.processName, app.uid);
9530                }
9531                app.bad = true;
9532                app.removed = true;
9533                // Don't let services in this process be restarted and potentially
9534                // annoy the user repeatedly.  Unless it is persistent, since those
9535                // processes run critical code.
9536                removeProcessLocked(app, false, false, "crash");
9537                mStackSupervisor.resumeTopActivitiesLocked();
9538                return false;
9539            }
9540            mStackSupervisor.resumeTopActivitiesLocked();
9541        } else {
9542            mStackSupervisor.finishTopRunningActivityLocked(app);
9543        }
9544
9545        // Bump up the crash count of any services currently running in the proc.
9546        for (int i=app.services.size()-1; i>=0; i--) {
9547            // Any services running in the application need to be placed
9548            // back in the pending list.
9549            ServiceRecord sr = app.services.valueAt(i);
9550            sr.crashCount++;
9551        }
9552
9553        // If the crashing process is what we consider to be the "home process" and it has been
9554        // replaced by a third-party app, clear the package preferred activities from packages
9555        // with a home activity running in the process to prevent a repeatedly crashing app
9556        // from blocking the user to manually clear the list.
9557        final ArrayList<ActivityRecord> activities = app.activities;
9558        if (app == mHomeProcess && activities.size() > 0
9559                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
9560            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
9561                final ActivityRecord r = activities.get(activityNdx);
9562                if (r.isHomeActivity()) {
9563                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
9564                    try {
9565                        ActivityThread.getPackageManager()
9566                                .clearPackagePreferredActivities(r.packageName);
9567                    } catch (RemoteException c) {
9568                        // pm is in same process, this will never happen.
9569                    }
9570                }
9571            }
9572        }
9573
9574        if (!app.isolated) {
9575            // XXX Can't keep track of crash times for isolated processes,
9576            // because they don't have a perisistent identity.
9577            mProcessCrashTimes.put(app.info.processName, app.uid, now);
9578        }
9579
9580        return true;
9581    }
9582
9583    void startAppProblemLocked(ProcessRecord app) {
9584        if (app.userId == mCurrentUserId) {
9585            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
9586                    mContext, app.info.packageName, app.info.flags);
9587        } else {
9588            // If this app is not running under the current user, then we
9589            // can't give it a report button because that would require
9590            // launching the report UI under a different user.
9591            app.errorReportReceiver = null;
9592        }
9593        skipCurrentReceiverLocked(app);
9594    }
9595
9596    void skipCurrentReceiverLocked(ProcessRecord app) {
9597        for (BroadcastQueue queue : mBroadcastQueues) {
9598            queue.skipCurrentReceiverLocked(app);
9599        }
9600    }
9601
9602    /**
9603     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
9604     * The application process will exit immediately after this call returns.
9605     * @param app object of the crashing app, null for the system server
9606     * @param crashInfo describing the exception
9607     */
9608    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
9609        ProcessRecord r = findAppProcess(app, "Crash");
9610        final String processName = app == null ? "system_server"
9611                : (r == null ? "unknown" : r.processName);
9612
9613        handleApplicationCrashInner("crash", r, processName, crashInfo);
9614    }
9615
9616    /* Native crash reporting uses this inner version because it needs to be somewhat
9617     * decoupled from the AM-managed cleanup lifecycle
9618     */
9619    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
9620            ApplicationErrorReport.CrashInfo crashInfo) {
9621        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
9622                UserHandle.getUserId(Binder.getCallingUid()), processName,
9623                r == null ? -1 : r.info.flags,
9624                crashInfo.exceptionClassName,
9625                crashInfo.exceptionMessage,
9626                crashInfo.throwFileName,
9627                crashInfo.throwLineNumber);
9628
9629        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
9630
9631        crashApplication(r, crashInfo);
9632    }
9633
9634    public void handleApplicationStrictModeViolation(
9635            IBinder app,
9636            int violationMask,
9637            StrictMode.ViolationInfo info) {
9638        ProcessRecord r = findAppProcess(app, "StrictMode");
9639        if (r == null) {
9640            return;
9641        }
9642
9643        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
9644            Integer stackFingerprint = info.hashCode();
9645            boolean logIt = true;
9646            synchronized (mAlreadyLoggedViolatedStacks) {
9647                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
9648                    logIt = false;
9649                    // TODO: sub-sample into EventLog for these, with
9650                    // the info.durationMillis?  Then we'd get
9651                    // the relative pain numbers, without logging all
9652                    // the stack traces repeatedly.  We'd want to do
9653                    // likewise in the client code, which also does
9654                    // dup suppression, before the Binder call.
9655                } else {
9656                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
9657                        mAlreadyLoggedViolatedStacks.clear();
9658                    }
9659                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
9660                }
9661            }
9662            if (logIt) {
9663                logStrictModeViolationToDropBox(r, info);
9664            }
9665        }
9666
9667        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
9668            AppErrorResult result = new AppErrorResult();
9669            synchronized (this) {
9670                final long origId = Binder.clearCallingIdentity();
9671
9672                Message msg = Message.obtain();
9673                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
9674                HashMap<String, Object> data = new HashMap<String, Object>();
9675                data.put("result", result);
9676                data.put("app", r);
9677                data.put("violationMask", violationMask);
9678                data.put("info", info);
9679                msg.obj = data;
9680                mHandler.sendMessage(msg);
9681
9682                Binder.restoreCallingIdentity(origId);
9683            }
9684            int res = result.get();
9685            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
9686        }
9687    }
9688
9689    // Depending on the policy in effect, there could be a bunch of
9690    // these in quick succession so we try to batch these together to
9691    // minimize disk writes, number of dropbox entries, and maximize
9692    // compression, by having more fewer, larger records.
9693    private void logStrictModeViolationToDropBox(
9694            ProcessRecord process,
9695            StrictMode.ViolationInfo info) {
9696        if (info == null) {
9697            return;
9698        }
9699        final boolean isSystemApp = process == null ||
9700                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
9701                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
9702        final String processName = process == null ? "unknown" : process.processName;
9703        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
9704        final DropBoxManager dbox = (DropBoxManager)
9705                mContext.getSystemService(Context.DROPBOX_SERVICE);
9706
9707        // Exit early if the dropbox isn't configured to accept this report type.
9708        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9709
9710        boolean bufferWasEmpty;
9711        boolean needsFlush;
9712        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
9713        synchronized (sb) {
9714            bufferWasEmpty = sb.length() == 0;
9715            appendDropBoxProcessHeaders(process, processName, sb);
9716            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9717            sb.append("System-App: ").append(isSystemApp).append("\n");
9718            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
9719            if (info.violationNumThisLoop != 0) {
9720                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
9721            }
9722            if (info.numAnimationsRunning != 0) {
9723                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
9724            }
9725            if (info.broadcastIntentAction != null) {
9726                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
9727            }
9728            if (info.durationMillis != -1) {
9729                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
9730            }
9731            if (info.numInstances != -1) {
9732                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
9733            }
9734            if (info.tags != null) {
9735                for (String tag : info.tags) {
9736                    sb.append("Span-Tag: ").append(tag).append("\n");
9737                }
9738            }
9739            sb.append("\n");
9740            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
9741                sb.append(info.crashInfo.stackTrace);
9742            }
9743            sb.append("\n");
9744
9745            // Only buffer up to ~64k.  Various logging bits truncate
9746            // things at 128k.
9747            needsFlush = (sb.length() > 64 * 1024);
9748        }
9749
9750        // Flush immediately if the buffer's grown too large, or this
9751        // is a non-system app.  Non-system apps are isolated with a
9752        // different tag & policy and not batched.
9753        //
9754        // Batching is useful during internal testing with
9755        // StrictMode settings turned up high.  Without batching,
9756        // thousands of separate files could be created on boot.
9757        if (!isSystemApp || needsFlush) {
9758            new Thread("Error dump: " + dropboxTag) {
9759                @Override
9760                public void run() {
9761                    String report;
9762                    synchronized (sb) {
9763                        report = sb.toString();
9764                        sb.delete(0, sb.length());
9765                        sb.trimToSize();
9766                    }
9767                    if (report.length() != 0) {
9768                        dbox.addText(dropboxTag, report);
9769                    }
9770                }
9771            }.start();
9772            return;
9773        }
9774
9775        // System app batching:
9776        if (!bufferWasEmpty) {
9777            // An existing dropbox-writing thread is outstanding, so
9778            // we don't need to start it up.  The existing thread will
9779            // catch the buffer appends we just did.
9780            return;
9781        }
9782
9783        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
9784        // (After this point, we shouldn't access AMS internal data structures.)
9785        new Thread("Error dump: " + dropboxTag) {
9786            @Override
9787            public void run() {
9788                // 5 second sleep to let stacks arrive and be batched together
9789                try {
9790                    Thread.sleep(5000);  // 5 seconds
9791                } catch (InterruptedException e) {}
9792
9793                String errorReport;
9794                synchronized (mStrictModeBuffer) {
9795                    errorReport = mStrictModeBuffer.toString();
9796                    if (errorReport.length() == 0) {
9797                        return;
9798                    }
9799                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
9800                    mStrictModeBuffer.trimToSize();
9801                }
9802                dbox.addText(dropboxTag, errorReport);
9803            }
9804        }.start();
9805    }
9806
9807    /**
9808     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
9809     * @param app object of the crashing app, null for the system server
9810     * @param tag reported by the caller
9811     * @param crashInfo describing the context of the error
9812     * @return true if the process should exit immediately (WTF is fatal)
9813     */
9814    public boolean handleApplicationWtf(IBinder app, String tag,
9815            ApplicationErrorReport.CrashInfo crashInfo) {
9816        ProcessRecord r = findAppProcess(app, "WTF");
9817        final String processName = app == null ? "system_server"
9818                : (r == null ? "unknown" : r.processName);
9819
9820        EventLog.writeEvent(EventLogTags.AM_WTF,
9821                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
9822                processName,
9823                r == null ? -1 : r.info.flags,
9824                tag, crashInfo.exceptionMessage);
9825
9826        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
9827
9828        if (r != null && r.pid != Process.myPid() &&
9829                Settings.Global.getInt(mContext.getContentResolver(),
9830                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
9831            crashApplication(r, crashInfo);
9832            return true;
9833        } else {
9834            return false;
9835        }
9836    }
9837
9838    /**
9839     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
9840     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
9841     */
9842    private ProcessRecord findAppProcess(IBinder app, String reason) {
9843        if (app == null) {
9844            return null;
9845        }
9846
9847        synchronized (this) {
9848            final int NP = mProcessNames.getMap().size();
9849            for (int ip=0; ip<NP; ip++) {
9850                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
9851                final int NA = apps.size();
9852                for (int ia=0; ia<NA; ia++) {
9853                    ProcessRecord p = apps.valueAt(ia);
9854                    if (p.thread != null && p.thread.asBinder() == app) {
9855                        return p;
9856                    }
9857                }
9858            }
9859
9860            Slog.w(TAG, "Can't find mystery application for " + reason
9861                    + " from pid=" + Binder.getCallingPid()
9862                    + " uid=" + Binder.getCallingUid() + ": " + app);
9863            return null;
9864        }
9865    }
9866
9867    /**
9868     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
9869     * to append various headers to the dropbox log text.
9870     */
9871    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
9872            StringBuilder sb) {
9873        // Watchdog thread ends up invoking this function (with
9874        // a null ProcessRecord) to add the stack file to dropbox.
9875        // Do not acquire a lock on this (am) in such cases, as it
9876        // could cause a potential deadlock, if and when watchdog
9877        // is invoked due to unavailability of lock on am and it
9878        // would prevent watchdog from killing system_server.
9879        if (process == null) {
9880            sb.append("Process: ").append(processName).append("\n");
9881            return;
9882        }
9883        // Note: ProcessRecord 'process' is guarded by the service
9884        // instance.  (notably process.pkgList, which could otherwise change
9885        // concurrently during execution of this method)
9886        synchronized (this) {
9887            sb.append("Process: ").append(processName).append("\n");
9888            int flags = process.info.flags;
9889            IPackageManager pm = AppGlobals.getPackageManager();
9890            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
9891            for (int ip=0; ip<process.pkgList.size(); ip++) {
9892                String pkg = process.pkgList.keyAt(ip);
9893                sb.append("Package: ").append(pkg);
9894                try {
9895                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
9896                    if (pi != null) {
9897                        sb.append(" v").append(pi.versionCode);
9898                        if (pi.versionName != null) {
9899                            sb.append(" (").append(pi.versionName).append(")");
9900                        }
9901                    }
9902                } catch (RemoteException e) {
9903                    Slog.e(TAG, "Error getting package info: " + pkg, e);
9904                }
9905                sb.append("\n");
9906            }
9907        }
9908    }
9909
9910    private static String processClass(ProcessRecord process) {
9911        if (process == null || process.pid == MY_PID) {
9912            return "system_server";
9913        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
9914            return "system_app";
9915        } else {
9916            return "data_app";
9917        }
9918    }
9919
9920    /**
9921     * Write a description of an error (crash, WTF, ANR) to the drop box.
9922     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
9923     * @param process which caused the error, null means the system server
9924     * @param activity which triggered the error, null if unknown
9925     * @param parent activity related to the error, null if unknown
9926     * @param subject line related to the error, null if absent
9927     * @param report in long form describing the error, null if absent
9928     * @param logFile to include in the report, null if none
9929     * @param crashInfo giving an application stack trace, null if absent
9930     */
9931    public void addErrorToDropBox(String eventType,
9932            ProcessRecord process, String processName, ActivityRecord activity,
9933            ActivityRecord parent, String subject,
9934            final String report, final File logFile,
9935            final ApplicationErrorReport.CrashInfo crashInfo) {
9936        // NOTE -- this must never acquire the ActivityManagerService lock,
9937        // otherwise the watchdog may be prevented from resetting the system.
9938
9939        final String dropboxTag = processClass(process) + "_" + eventType;
9940        final DropBoxManager dbox = (DropBoxManager)
9941                mContext.getSystemService(Context.DROPBOX_SERVICE);
9942
9943        // Exit early if the dropbox isn't configured to accept this report type.
9944        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
9945
9946        final StringBuilder sb = new StringBuilder(1024);
9947        appendDropBoxProcessHeaders(process, processName, sb);
9948        if (activity != null) {
9949            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
9950        }
9951        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
9952            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
9953        }
9954        if (parent != null && parent != activity) {
9955            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
9956        }
9957        if (subject != null) {
9958            sb.append("Subject: ").append(subject).append("\n");
9959        }
9960        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
9961        if (Debug.isDebuggerConnected()) {
9962            sb.append("Debugger: Connected\n");
9963        }
9964        sb.append("\n");
9965
9966        // Do the rest in a worker thread to avoid blocking the caller on I/O
9967        // (After this point, we shouldn't access AMS internal data structures.)
9968        Thread worker = new Thread("Error dump: " + dropboxTag) {
9969            @Override
9970            public void run() {
9971                if (report != null) {
9972                    sb.append(report);
9973                }
9974                if (logFile != null) {
9975                    try {
9976                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
9977                                    "\n\n[[TRUNCATED]]"));
9978                    } catch (IOException e) {
9979                        Slog.e(TAG, "Error reading " + logFile, e);
9980                    }
9981                }
9982                if (crashInfo != null && crashInfo.stackTrace != null) {
9983                    sb.append(crashInfo.stackTrace);
9984                }
9985
9986                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
9987                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
9988                if (lines > 0) {
9989                    sb.append("\n");
9990
9991                    // Merge several logcat streams, and take the last N lines
9992                    InputStreamReader input = null;
9993                    try {
9994                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
9995                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
9996                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
9997
9998                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
9999                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10000                        input = new InputStreamReader(logcat.getInputStream());
10001
10002                        int num;
10003                        char[] buf = new char[8192];
10004                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10005                    } catch (IOException e) {
10006                        Slog.e(TAG, "Error running logcat", e);
10007                    } finally {
10008                        if (input != null) try { input.close(); } catch (IOException e) {}
10009                    }
10010                }
10011
10012                dbox.addText(dropboxTag, sb.toString());
10013            }
10014        };
10015
10016        if (process == null) {
10017            // If process is null, we are being called from some internal code
10018            // and may be about to die -- run this synchronously.
10019            worker.run();
10020        } else {
10021            worker.start();
10022        }
10023    }
10024
10025    /**
10026     * Bring up the "unexpected error" dialog box for a crashing app.
10027     * Deal with edge cases (intercepts from instrumented applications,
10028     * ActivityController, error intent receivers, that sort of thing).
10029     * @param r the application crashing
10030     * @param crashInfo describing the failure
10031     */
10032    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10033        long timeMillis = System.currentTimeMillis();
10034        String shortMsg = crashInfo.exceptionClassName;
10035        String longMsg = crashInfo.exceptionMessage;
10036        String stackTrace = crashInfo.stackTrace;
10037        if (shortMsg != null && longMsg != null) {
10038            longMsg = shortMsg + ": " + longMsg;
10039        } else if (shortMsg != null) {
10040            longMsg = shortMsg;
10041        }
10042
10043        AppErrorResult result = new AppErrorResult();
10044        synchronized (this) {
10045            if (mController != null) {
10046                try {
10047                    String name = r != null ? r.processName : null;
10048                    int pid = r != null ? r.pid : Binder.getCallingPid();
10049                    if (!mController.appCrashed(name, pid,
10050                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10051                        Slog.w(TAG, "Force-killing crashed app " + name
10052                                + " at watcher's request");
10053                        Process.killProcess(pid);
10054                        return;
10055                    }
10056                } catch (RemoteException e) {
10057                    mController = null;
10058                    Watchdog.getInstance().setActivityController(null);
10059                }
10060            }
10061
10062            final long origId = Binder.clearCallingIdentity();
10063
10064            // If this process is running instrumentation, finish it.
10065            if (r != null && r.instrumentationClass != null) {
10066                Slog.w(TAG, "Error in app " + r.processName
10067                      + " running instrumentation " + r.instrumentationClass + ":");
10068                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10069                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10070                Bundle info = new Bundle();
10071                info.putString("shortMsg", shortMsg);
10072                info.putString("longMsg", longMsg);
10073                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10074                Binder.restoreCallingIdentity(origId);
10075                return;
10076            }
10077
10078            // If we can't identify the process or it's already exceeded its crash quota,
10079            // quit right away without showing a crash dialog.
10080            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10081                Binder.restoreCallingIdentity(origId);
10082                return;
10083            }
10084
10085            Message msg = Message.obtain();
10086            msg.what = SHOW_ERROR_MSG;
10087            HashMap data = new HashMap();
10088            data.put("result", result);
10089            data.put("app", r);
10090            msg.obj = data;
10091            mHandler.sendMessage(msg);
10092
10093            Binder.restoreCallingIdentity(origId);
10094        }
10095
10096        int res = result.get();
10097
10098        Intent appErrorIntent = null;
10099        synchronized (this) {
10100            if (r != null && !r.isolated) {
10101                // XXX Can't keep track of crash time for isolated processes,
10102                // since they don't have a persistent identity.
10103                mProcessCrashTimes.put(r.info.processName, r.uid,
10104                        SystemClock.uptimeMillis());
10105            }
10106            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10107                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10108            }
10109        }
10110
10111        if (appErrorIntent != null) {
10112            try {
10113                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10114            } catch (ActivityNotFoundException e) {
10115                Slog.w(TAG, "bug report receiver dissappeared", e);
10116            }
10117        }
10118    }
10119
10120    Intent createAppErrorIntentLocked(ProcessRecord r,
10121            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10122        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10123        if (report == null) {
10124            return null;
10125        }
10126        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10127        result.setComponent(r.errorReportReceiver);
10128        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10129        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10130        return result;
10131    }
10132
10133    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10134            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10135        if (r.errorReportReceiver == null) {
10136            return null;
10137        }
10138
10139        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10140            return null;
10141        }
10142
10143        ApplicationErrorReport report = new ApplicationErrorReport();
10144        report.packageName = r.info.packageName;
10145        report.installerPackageName = r.errorReportReceiver.getPackageName();
10146        report.processName = r.processName;
10147        report.time = timeMillis;
10148        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10149
10150        if (r.crashing || r.forceCrashReport) {
10151            report.type = ApplicationErrorReport.TYPE_CRASH;
10152            report.crashInfo = crashInfo;
10153        } else if (r.notResponding) {
10154            report.type = ApplicationErrorReport.TYPE_ANR;
10155            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10156
10157            report.anrInfo.activity = r.notRespondingReport.tag;
10158            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10159            report.anrInfo.info = r.notRespondingReport.longMsg;
10160        }
10161
10162        return report;
10163    }
10164
10165    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10166        enforceNotIsolatedCaller("getProcessesInErrorState");
10167        // assume our apps are happy - lazy create the list
10168        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10169
10170        final boolean allUsers = ActivityManager.checkUidPermission(
10171                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10172                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10173        int userId = UserHandle.getUserId(Binder.getCallingUid());
10174
10175        synchronized (this) {
10176
10177            // iterate across all processes
10178            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10179                ProcessRecord app = mLruProcesses.get(i);
10180                if (!allUsers && app.userId != userId) {
10181                    continue;
10182                }
10183                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10184                    // This one's in trouble, so we'll generate a report for it
10185                    // crashes are higher priority (in case there's a crash *and* an anr)
10186                    ActivityManager.ProcessErrorStateInfo report = null;
10187                    if (app.crashing) {
10188                        report = app.crashingReport;
10189                    } else if (app.notResponding) {
10190                        report = app.notRespondingReport;
10191                    }
10192
10193                    if (report != null) {
10194                        if (errList == null) {
10195                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10196                        }
10197                        errList.add(report);
10198                    } else {
10199                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10200                                " crashing = " + app.crashing +
10201                                " notResponding = " + app.notResponding);
10202                    }
10203                }
10204            }
10205        }
10206
10207        return errList;
10208    }
10209
10210    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10211        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10212            if (currApp != null) {
10213                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10214            }
10215            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10216        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10217            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10218        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10219            if (currApp != null) {
10220                currApp.lru = 0;
10221            }
10222            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10223        } else if (adj >= ProcessList.SERVICE_ADJ) {
10224            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10225        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10226            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10227        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10228            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10229        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10230            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10231        } else {
10232            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10233        }
10234    }
10235
10236    private void fillInProcMemInfo(ProcessRecord app,
10237            ActivityManager.RunningAppProcessInfo outInfo) {
10238        outInfo.pid = app.pid;
10239        outInfo.uid = app.info.uid;
10240        if (mHeavyWeightProcess == app) {
10241            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10242        }
10243        if (app.persistent) {
10244            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10245        }
10246        if (app.activities.size() > 0) {
10247            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10248        }
10249        outInfo.lastTrimLevel = app.trimMemoryLevel;
10250        int adj = app.curAdj;
10251        outInfo.importance = oomAdjToImportance(adj, outInfo);
10252        outInfo.importanceReasonCode = app.adjTypeCode;
10253    }
10254
10255    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10256        enforceNotIsolatedCaller("getRunningAppProcesses");
10257        // Lazy instantiation of list
10258        List<ActivityManager.RunningAppProcessInfo> runList = null;
10259        final boolean allUsers = ActivityManager.checkUidPermission(
10260                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10261                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10262        int userId = UserHandle.getUserId(Binder.getCallingUid());
10263        synchronized (this) {
10264            // Iterate across all processes
10265            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10266                ProcessRecord app = mLruProcesses.get(i);
10267                if (!allUsers && app.userId != userId) {
10268                    continue;
10269                }
10270                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10271                    // Generate process state info for running application
10272                    ActivityManager.RunningAppProcessInfo currApp =
10273                        new ActivityManager.RunningAppProcessInfo(app.processName,
10274                                app.pid, app.getPackageList());
10275                    fillInProcMemInfo(app, currApp);
10276                    if (app.adjSource instanceof ProcessRecord) {
10277                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10278                        currApp.importanceReasonImportance = oomAdjToImportance(
10279                                app.adjSourceOom, null);
10280                    } else if (app.adjSource instanceof ActivityRecord) {
10281                        ActivityRecord r = (ActivityRecord)app.adjSource;
10282                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10283                    }
10284                    if (app.adjTarget instanceof ComponentName) {
10285                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10286                    }
10287                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10288                    //        + " lru=" + currApp.lru);
10289                    if (runList == null) {
10290                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10291                    }
10292                    runList.add(currApp);
10293                }
10294            }
10295        }
10296        return runList;
10297    }
10298
10299    public List<ApplicationInfo> getRunningExternalApplications() {
10300        enforceNotIsolatedCaller("getRunningExternalApplications");
10301        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10302        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10303        if (runningApps != null && runningApps.size() > 0) {
10304            Set<String> extList = new HashSet<String>();
10305            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10306                if (app.pkgList != null) {
10307                    for (String pkg : app.pkgList) {
10308                        extList.add(pkg);
10309                    }
10310                }
10311            }
10312            IPackageManager pm = AppGlobals.getPackageManager();
10313            for (String pkg : extList) {
10314                try {
10315                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10316                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10317                        retList.add(info);
10318                    }
10319                } catch (RemoteException e) {
10320                }
10321            }
10322        }
10323        return retList;
10324    }
10325
10326    @Override
10327    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10328        enforceNotIsolatedCaller("getMyMemoryState");
10329        synchronized (this) {
10330            ProcessRecord proc;
10331            synchronized (mPidsSelfLocked) {
10332                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10333            }
10334            fillInProcMemInfo(proc, outInfo);
10335        }
10336    }
10337
10338    @Override
10339    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10340        if (checkCallingPermission(android.Manifest.permission.DUMP)
10341                != PackageManager.PERMISSION_GRANTED) {
10342            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10343                    + Binder.getCallingPid()
10344                    + ", uid=" + Binder.getCallingUid()
10345                    + " without permission "
10346                    + android.Manifest.permission.DUMP);
10347            return;
10348        }
10349
10350        boolean dumpAll = false;
10351        boolean dumpClient = false;
10352        String dumpPackage = null;
10353
10354        int opti = 0;
10355        while (opti < args.length) {
10356            String opt = args[opti];
10357            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10358                break;
10359            }
10360            opti++;
10361            if ("-a".equals(opt)) {
10362                dumpAll = true;
10363            } else if ("-c".equals(opt)) {
10364                dumpClient = true;
10365            } else if ("-h".equals(opt)) {
10366                pw.println("Activity manager dump options:");
10367                pw.println("  [-a] [-c] [-h] [cmd] ...");
10368                pw.println("  cmd may be one of:");
10369                pw.println("    a[ctivities]: activity stack state");
10370                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10371                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10372                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10373                pw.println("    o[om]: out of memory management");
10374                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10375                pw.println("    provider [COMP_SPEC]: provider client-side state");
10376                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10377                pw.println("    service [COMP_SPEC]: service client-side state");
10378                pw.println("    package [PACKAGE_NAME]: all state related to given package");
10379                pw.println("    all: dump all activities");
10380                pw.println("    top: dump the top activity");
10381                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
10382                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
10383                pw.println("    a partial substring in a component name, a");
10384                pw.println("    hex object identifier.");
10385                pw.println("  -a: include all available server state.");
10386                pw.println("  -c: include client state.");
10387                return;
10388            } else {
10389                pw.println("Unknown argument: " + opt + "; use -h for help");
10390            }
10391        }
10392
10393        long origId = Binder.clearCallingIdentity();
10394        boolean more = false;
10395        // Is the caller requesting to dump a particular piece of data?
10396        if (opti < args.length) {
10397            String cmd = args[opti];
10398            opti++;
10399            if ("activities".equals(cmd) || "a".equals(cmd)) {
10400                synchronized (this) {
10401                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
10402                }
10403            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
10404                String[] newArgs;
10405                String name;
10406                if (opti >= args.length) {
10407                    name = null;
10408                    newArgs = EMPTY_STRING_ARRAY;
10409                } else {
10410                    name = args[opti];
10411                    opti++;
10412                    newArgs = new String[args.length - opti];
10413                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10414                            args.length - opti);
10415                }
10416                synchronized (this) {
10417                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
10418                }
10419            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
10420                String[] newArgs;
10421                String name;
10422                if (opti >= args.length) {
10423                    name = null;
10424                    newArgs = EMPTY_STRING_ARRAY;
10425                } else {
10426                    name = args[opti];
10427                    opti++;
10428                    newArgs = new String[args.length - opti];
10429                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10430                            args.length - opti);
10431                }
10432                synchronized (this) {
10433                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
10434                }
10435            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
10436                String[] newArgs;
10437                String name;
10438                if (opti >= args.length) {
10439                    name = null;
10440                    newArgs = EMPTY_STRING_ARRAY;
10441                } else {
10442                    name = args[opti];
10443                    opti++;
10444                    newArgs = new String[args.length - opti];
10445                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10446                            args.length - opti);
10447                }
10448                synchronized (this) {
10449                    dumpProcessesLocked(fd, pw, args, opti, true, name);
10450                }
10451            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
10452                synchronized (this) {
10453                    dumpOomLocked(fd, pw, args, opti, true);
10454                }
10455            } else if ("provider".equals(cmd)) {
10456                String[] newArgs;
10457                String name;
10458                if (opti >= args.length) {
10459                    name = null;
10460                    newArgs = EMPTY_STRING_ARRAY;
10461                } else {
10462                    name = args[opti];
10463                    opti++;
10464                    newArgs = new String[args.length - opti];
10465                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
10466                }
10467                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
10468                    pw.println("No providers match: " + name);
10469                    pw.println("Use -h for help.");
10470                }
10471            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
10472                synchronized (this) {
10473                    dumpProvidersLocked(fd, pw, args, opti, true, null);
10474                }
10475            } else if ("service".equals(cmd)) {
10476                String[] newArgs;
10477                String name;
10478                if (opti >= args.length) {
10479                    name = null;
10480                    newArgs = EMPTY_STRING_ARRAY;
10481                } else {
10482                    name = args[opti];
10483                    opti++;
10484                    newArgs = new String[args.length - opti];
10485                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10486                            args.length - opti);
10487                }
10488                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
10489                    pw.println("No services match: " + name);
10490                    pw.println("Use -h for help.");
10491                }
10492            } else if ("package".equals(cmd)) {
10493                String[] newArgs;
10494                if (opti >= args.length) {
10495                    pw.println("package: no package name specified");
10496                    pw.println("Use -h for help.");
10497                } else {
10498                    dumpPackage = args[opti];
10499                    opti++;
10500                    newArgs = new String[args.length - opti];
10501                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
10502                            args.length - opti);
10503                    args = newArgs;
10504                    opti = 0;
10505                    more = true;
10506                }
10507            } else if ("services".equals(cmd) || "s".equals(cmd)) {
10508                synchronized (this) {
10509                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
10510                }
10511            } else {
10512                // Dumping a single activity?
10513                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
10514                    pw.println("Bad activity command, or no activities match: " + cmd);
10515                    pw.println("Use -h for help.");
10516                }
10517            }
10518            if (!more) {
10519                Binder.restoreCallingIdentity(origId);
10520                return;
10521            }
10522        }
10523
10524        // No piece of data specified, dump everything.
10525        synchronized (this) {
10526            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10527            pw.println();
10528            if (dumpAll) {
10529                pw.println("-------------------------------------------------------------------------------");
10530            }
10531            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10532            pw.println();
10533            if (dumpAll) {
10534                pw.println("-------------------------------------------------------------------------------");
10535            }
10536            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10537            pw.println();
10538            if (dumpAll) {
10539                pw.println("-------------------------------------------------------------------------------");
10540            }
10541            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10542            pw.println();
10543            if (dumpAll) {
10544                pw.println("-------------------------------------------------------------------------------");
10545            }
10546            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
10547            pw.println();
10548            if (dumpAll) {
10549                pw.println("-------------------------------------------------------------------------------");
10550            }
10551            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
10552        }
10553        Binder.restoreCallingIdentity(origId);
10554    }
10555
10556    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10557            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
10558        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
10559
10560        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
10561                dumpPackage);
10562        boolean needSep = printedAnything;
10563
10564        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
10565                dumpPackage, needSep, "  mFocusedActivity: ");
10566        if (printed) {
10567            printedAnything = true;
10568            needSep = false;
10569        }
10570
10571        if (dumpPackage == null) {
10572            if (needSep) {
10573                pw.println();
10574            }
10575            needSep = true;
10576            printedAnything = true;
10577            mStackSupervisor.dump(pw, "  ");
10578        }
10579
10580        if (mRecentTasks.size() > 0) {
10581            boolean printedHeader = false;
10582
10583            final int N = mRecentTasks.size();
10584            for (int i=0; i<N; i++) {
10585                TaskRecord tr = mRecentTasks.get(i);
10586                if (dumpPackage != null) {
10587                    if (tr.realActivity == null ||
10588                            !dumpPackage.equals(tr.realActivity)) {
10589                        continue;
10590                    }
10591                }
10592                if (!printedHeader) {
10593                    if (needSep) {
10594                        pw.println();
10595                    }
10596                    pw.println("  Recent tasks:");
10597                    printedHeader = true;
10598                    printedAnything = true;
10599                }
10600                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
10601                        pw.println(tr);
10602                if (dumpAll) {
10603                    mRecentTasks.get(i).dump(pw, "    ");
10604                }
10605            }
10606        }
10607
10608        if (!printedAnything) {
10609            pw.println("  (nothing)");
10610        }
10611    }
10612
10613    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
10614            int opti, boolean dumpAll, String dumpPackage) {
10615        boolean needSep = false;
10616        boolean printedAnything = false;
10617        int numPers = 0;
10618
10619        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
10620
10621        if (dumpAll) {
10622            final int NP = mProcessNames.getMap().size();
10623            for (int ip=0; ip<NP; ip++) {
10624                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
10625                final int NA = procs.size();
10626                for (int ia=0; ia<NA; ia++) {
10627                    ProcessRecord r = procs.valueAt(ia);
10628                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10629                        continue;
10630                    }
10631                    if (!needSep) {
10632                        pw.println("  All known processes:");
10633                        needSep = true;
10634                        printedAnything = true;
10635                    }
10636                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
10637                        pw.print(" UID "); pw.print(procs.keyAt(ia));
10638                        pw.print(" "); pw.println(r);
10639                    r.dump(pw, "    ");
10640                    if (r.persistent) {
10641                        numPers++;
10642                    }
10643                }
10644            }
10645        }
10646
10647        if (mIsolatedProcesses.size() > 0) {
10648            boolean printed = false;
10649            for (int i=0; i<mIsolatedProcesses.size(); i++) {
10650                ProcessRecord r = mIsolatedProcesses.valueAt(i);
10651                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10652                    continue;
10653                }
10654                if (!printed) {
10655                    if (needSep) {
10656                        pw.println();
10657                    }
10658                    pw.println("  Isolated process list (sorted by uid):");
10659                    printedAnything = true;
10660                    printed = true;
10661                    needSep = true;
10662                }
10663                pw.println(String.format("%sIsolated #%2d: %s",
10664                        "    ", i, r.toString()));
10665            }
10666        }
10667
10668        if (mLruProcesses.size() > 0) {
10669            if (needSep) {
10670                pw.println();
10671            }
10672            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
10673                    pw.print(" total, non-act at ");
10674                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
10675                    pw.print(", non-svc at ");
10676                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
10677                    pw.println("):");
10678            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
10679            needSep = true;
10680            printedAnything = true;
10681        }
10682
10683        if (dumpAll || dumpPackage != null) {
10684            synchronized (mPidsSelfLocked) {
10685                boolean printed = false;
10686                for (int i=0; i<mPidsSelfLocked.size(); i++) {
10687                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
10688                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
10689                        continue;
10690                    }
10691                    if (!printed) {
10692                        if (needSep) pw.println();
10693                        needSep = true;
10694                        pw.println("  PID mappings:");
10695                        printed = true;
10696                        printedAnything = true;
10697                    }
10698                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
10699                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
10700                }
10701            }
10702        }
10703
10704        if (mForegroundProcesses.size() > 0) {
10705            synchronized (mPidsSelfLocked) {
10706                boolean printed = false;
10707                for (int i=0; i<mForegroundProcesses.size(); i++) {
10708                    ProcessRecord r = mPidsSelfLocked.get(
10709                            mForegroundProcesses.valueAt(i).pid);
10710                    if (dumpPackage != null && (r == null
10711                            || !r.pkgList.containsKey(dumpPackage))) {
10712                        continue;
10713                    }
10714                    if (!printed) {
10715                        if (needSep) pw.println();
10716                        needSep = true;
10717                        pw.println("  Foreground Processes:");
10718                        printed = true;
10719                        printedAnything = true;
10720                    }
10721                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
10722                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
10723                }
10724            }
10725        }
10726
10727        if (mPersistentStartingProcesses.size() > 0) {
10728            if (needSep) pw.println();
10729            needSep = true;
10730            printedAnything = true;
10731            pw.println("  Persisent processes that are starting:");
10732            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
10733                    "Starting Norm", "Restarting PERS", dumpPackage);
10734        }
10735
10736        if (mRemovedProcesses.size() > 0) {
10737            if (needSep) pw.println();
10738            needSep = true;
10739            printedAnything = true;
10740            pw.println("  Processes that are being removed:");
10741            dumpProcessList(pw, this, mRemovedProcesses, "    ",
10742                    "Removed Norm", "Removed PERS", dumpPackage);
10743        }
10744
10745        if (mProcessesOnHold.size() > 0) {
10746            if (needSep) pw.println();
10747            needSep = true;
10748            printedAnything = true;
10749            pw.println("  Processes that are on old until the system is ready:");
10750            dumpProcessList(pw, this, mProcessesOnHold, "    ",
10751                    "OnHold Norm", "OnHold PERS", dumpPackage);
10752        }
10753
10754        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
10755
10756        if (mProcessCrashTimes.getMap().size() > 0) {
10757            boolean printed = false;
10758            long now = SystemClock.uptimeMillis();
10759            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
10760            final int NP = pmap.size();
10761            for (int ip=0; ip<NP; ip++) {
10762                String pname = pmap.keyAt(ip);
10763                SparseArray<Long> uids = pmap.valueAt(ip);
10764                final int N = uids.size();
10765                for (int i=0; i<N; i++) {
10766                    int puid = uids.keyAt(i);
10767                    ProcessRecord r = mProcessNames.get(pname, puid);
10768                    if (dumpPackage != null && (r == null
10769                            || !r.pkgList.containsKey(dumpPackage))) {
10770                        continue;
10771                    }
10772                    if (!printed) {
10773                        if (needSep) pw.println();
10774                        needSep = true;
10775                        pw.println("  Time since processes crashed:");
10776                        printed = true;
10777                        printedAnything = true;
10778                    }
10779                    pw.print("    Process "); pw.print(pname);
10780                            pw.print(" uid "); pw.print(puid);
10781                            pw.print(": last crashed ");
10782                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
10783                            pw.println(" ago");
10784                }
10785            }
10786        }
10787
10788        if (mBadProcesses.getMap().size() > 0) {
10789            boolean printed = false;
10790            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
10791            final int NP = pmap.size();
10792            for (int ip=0; ip<NP; ip++) {
10793                String pname = pmap.keyAt(ip);
10794                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
10795                final int N = uids.size();
10796                for (int i=0; i<N; i++) {
10797                    int puid = uids.keyAt(i);
10798                    ProcessRecord r = mProcessNames.get(pname, puid);
10799                    if (dumpPackage != null && (r == null
10800                            || !r.pkgList.containsKey(dumpPackage))) {
10801                        continue;
10802                    }
10803                    if (!printed) {
10804                        if (needSep) pw.println();
10805                        needSep = true;
10806                        pw.println("  Bad processes:");
10807                        printedAnything = true;
10808                    }
10809                    BadProcessInfo info = uids.valueAt(i);
10810                    pw.print("    Bad process "); pw.print(pname);
10811                            pw.print(" uid "); pw.print(puid);
10812                            pw.print(": crashed at time "); pw.println(info.time);
10813                    if (info.shortMsg != null) {
10814                        pw.print("      Short msg: "); pw.println(info.shortMsg);
10815                    }
10816                    if (info.longMsg != null) {
10817                        pw.print("      Long msg: "); pw.println(info.longMsg);
10818                    }
10819                    if (info.stack != null) {
10820                        pw.println("      Stack:");
10821                        int lastPos = 0;
10822                        for (int pos=0; pos<info.stack.length(); pos++) {
10823                            if (info.stack.charAt(pos) == '\n') {
10824                                pw.print("        ");
10825                                pw.write(info.stack, lastPos, pos-lastPos);
10826                                pw.println();
10827                                lastPos = pos+1;
10828                            }
10829                        }
10830                        if (lastPos < info.stack.length()) {
10831                            pw.print("        ");
10832                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
10833                            pw.println();
10834                        }
10835                    }
10836                }
10837            }
10838        }
10839
10840        if (dumpPackage == null) {
10841            pw.println();
10842            needSep = false;
10843            pw.println("  mStartedUsers:");
10844            for (int i=0; i<mStartedUsers.size(); i++) {
10845                UserStartedState uss = mStartedUsers.valueAt(i);
10846                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
10847                        pw.print(": "); uss.dump("", pw);
10848            }
10849            pw.print("  mStartedUserArray: [");
10850            for (int i=0; i<mStartedUserArray.length; i++) {
10851                if (i > 0) pw.print(", ");
10852                pw.print(mStartedUserArray[i]);
10853            }
10854            pw.println("]");
10855            pw.print("  mUserLru: [");
10856            for (int i=0; i<mUserLru.size(); i++) {
10857                if (i > 0) pw.print(", ");
10858                pw.print(mUserLru.get(i));
10859            }
10860            pw.println("]");
10861            if (dumpAll) {
10862                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
10863            }
10864        }
10865        if (mHomeProcess != null && (dumpPackage == null
10866                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
10867            if (needSep) {
10868                pw.println();
10869                needSep = false;
10870            }
10871            pw.println("  mHomeProcess: " + mHomeProcess);
10872        }
10873        if (mPreviousProcess != null && (dumpPackage == null
10874                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
10875            if (needSep) {
10876                pw.println();
10877                needSep = false;
10878            }
10879            pw.println("  mPreviousProcess: " + mPreviousProcess);
10880        }
10881        if (dumpAll) {
10882            StringBuilder sb = new StringBuilder(128);
10883            sb.append("  mPreviousProcessVisibleTime: ");
10884            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
10885            pw.println(sb);
10886        }
10887        if (mHeavyWeightProcess != null && (dumpPackage == null
10888                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
10889            if (needSep) {
10890                pw.println();
10891                needSep = false;
10892            }
10893            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
10894        }
10895        if (dumpPackage == null) {
10896            pw.println("  mConfiguration: " + mConfiguration);
10897        }
10898        if (dumpAll) {
10899            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
10900            if (mCompatModePackages.getPackages().size() > 0) {
10901                boolean printed = false;
10902                for (Map.Entry<String, Integer> entry
10903                        : mCompatModePackages.getPackages().entrySet()) {
10904                    String pkg = entry.getKey();
10905                    int mode = entry.getValue();
10906                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
10907                        continue;
10908                    }
10909                    if (!printed) {
10910                        pw.println("  mScreenCompatPackages:");
10911                        printed = true;
10912                    }
10913                    pw.print("    "); pw.print(pkg); pw.print(": ");
10914                            pw.print(mode); pw.println();
10915                }
10916            }
10917        }
10918        if (dumpPackage == null) {
10919            if (mSleeping || mWentToSleep || mLockScreenShown) {
10920                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
10921                        + " mLockScreenShown " + mLockScreenShown);
10922            }
10923            if (mShuttingDown) {
10924                pw.println("  mShuttingDown=" + mShuttingDown);
10925            }
10926        }
10927        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
10928                || mOrigWaitForDebugger) {
10929            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
10930                    || dumpPackage.equals(mOrigDebugApp)) {
10931                if (needSep) {
10932                    pw.println();
10933                    needSep = false;
10934                }
10935                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
10936                        + " mDebugTransient=" + mDebugTransient
10937                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
10938            }
10939        }
10940        if (mOpenGlTraceApp != null) {
10941            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
10942                if (needSep) {
10943                    pw.println();
10944                    needSep = false;
10945                }
10946                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
10947            }
10948        }
10949        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
10950                || mProfileFd != null) {
10951            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
10952                if (needSep) {
10953                    pw.println();
10954                    needSep = false;
10955                }
10956                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
10957                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
10958                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
10959                        + mAutoStopProfiler);
10960            }
10961        }
10962        if (dumpPackage == null) {
10963            if (mAlwaysFinishActivities || mController != null) {
10964                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
10965                        + " mController=" + mController);
10966            }
10967            if (dumpAll) {
10968                pw.println("  Total persistent processes: " + numPers);
10969                pw.println("  mStartRunning=" + mStartRunning
10970                        + " mProcessesReady=" + mProcessesReady
10971                        + " mSystemReady=" + mSystemReady);
10972                pw.println("  mBooting=" + mBooting
10973                        + " mBooted=" + mBooted
10974                        + " mFactoryTest=" + mFactoryTest);
10975                pw.print("  mLastPowerCheckRealtime=");
10976                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
10977                        pw.println("");
10978                pw.print("  mLastPowerCheckUptime=");
10979                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
10980                        pw.println("");
10981                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
10982                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
10983                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
10984                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
10985                        + " (" + mLruProcesses.size() + " total)"
10986                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
10987                        + " mNumServiceProcs=" + mNumServiceProcs
10988                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
10989                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
10990                        + " mLastMemoryLevel" + mLastMemoryLevel
10991                        + " mLastNumProcesses" + mLastNumProcesses);
10992                long now = SystemClock.uptimeMillis();
10993                pw.print("  mLastIdleTime=");
10994                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
10995                        pw.print(" mLowRamSinceLastIdle=");
10996                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
10997                        pw.println();
10998            }
10999        }
11000
11001        if (!printedAnything) {
11002            pw.println("  (nothing)");
11003        }
11004    }
11005
11006    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11007            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11008        if (mProcessesToGc.size() > 0) {
11009            boolean printed = false;
11010            long now = SystemClock.uptimeMillis();
11011            for (int i=0; i<mProcessesToGc.size(); i++) {
11012                ProcessRecord proc = mProcessesToGc.get(i);
11013                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11014                    continue;
11015                }
11016                if (!printed) {
11017                    if (needSep) pw.println();
11018                    needSep = true;
11019                    pw.println("  Processes that are waiting to GC:");
11020                    printed = true;
11021                }
11022                pw.print("    Process "); pw.println(proc);
11023                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11024                        pw.print(", last gced=");
11025                        pw.print(now-proc.lastRequestedGc);
11026                        pw.print(" ms ago, last lowMem=");
11027                        pw.print(now-proc.lastLowMemory);
11028                        pw.println(" ms ago");
11029
11030            }
11031        }
11032        return needSep;
11033    }
11034
11035    void printOomLevel(PrintWriter pw, String name, int adj) {
11036        pw.print("    ");
11037        if (adj >= 0) {
11038            pw.print(' ');
11039            if (adj < 10) pw.print(' ');
11040        } else {
11041            if (adj > -10) pw.print(' ');
11042        }
11043        pw.print(adj);
11044        pw.print(": ");
11045        pw.print(name);
11046        pw.print(" (");
11047        pw.print(mProcessList.getMemLevel(adj)/1024);
11048        pw.println(" kB)");
11049    }
11050
11051    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11052            int opti, boolean dumpAll) {
11053        boolean needSep = false;
11054
11055        if (mLruProcesses.size() > 0) {
11056            if (needSep) pw.println();
11057            needSep = true;
11058            pw.println("  OOM levels:");
11059            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11060            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11061            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11062            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11063            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11064            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11065            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11066            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11067            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11068            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11069            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11070            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11071            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11072
11073            if (needSep) pw.println();
11074            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11075                    pw.print(" total, non-act at ");
11076                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11077                    pw.print(", non-svc at ");
11078                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11079                    pw.println("):");
11080            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11081            needSep = true;
11082        }
11083
11084        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11085
11086        pw.println();
11087        pw.println("  mHomeProcess: " + mHomeProcess);
11088        pw.println("  mPreviousProcess: " + mPreviousProcess);
11089        if (mHeavyWeightProcess != null) {
11090            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11091        }
11092
11093        return true;
11094    }
11095
11096    /**
11097     * There are three ways to call this:
11098     *  - no provider specified: dump all the providers
11099     *  - a flattened component name that matched an existing provider was specified as the
11100     *    first arg: dump that one provider
11101     *  - the first arg isn't the flattened component name of an existing provider:
11102     *    dump all providers whose component contains the first arg as a substring
11103     */
11104    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11105            int opti, boolean dumpAll) {
11106        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11107    }
11108
11109    static class ItemMatcher {
11110        ArrayList<ComponentName> components;
11111        ArrayList<String> strings;
11112        ArrayList<Integer> objects;
11113        boolean all;
11114
11115        ItemMatcher() {
11116            all = true;
11117        }
11118
11119        void build(String name) {
11120            ComponentName componentName = ComponentName.unflattenFromString(name);
11121            if (componentName != null) {
11122                if (components == null) {
11123                    components = new ArrayList<ComponentName>();
11124                }
11125                components.add(componentName);
11126                all = false;
11127            } else {
11128                int objectId = 0;
11129                // Not a '/' separated full component name; maybe an object ID?
11130                try {
11131                    objectId = Integer.parseInt(name, 16);
11132                    if (objects == null) {
11133                        objects = new ArrayList<Integer>();
11134                    }
11135                    objects.add(objectId);
11136                    all = false;
11137                } catch (RuntimeException e) {
11138                    // Not an integer; just do string match.
11139                    if (strings == null) {
11140                        strings = new ArrayList<String>();
11141                    }
11142                    strings.add(name);
11143                    all = false;
11144                }
11145            }
11146        }
11147
11148        int build(String[] args, int opti) {
11149            for (; opti<args.length; opti++) {
11150                String name = args[opti];
11151                if ("--".equals(name)) {
11152                    return opti+1;
11153                }
11154                build(name);
11155            }
11156            return opti;
11157        }
11158
11159        boolean match(Object object, ComponentName comp) {
11160            if (all) {
11161                return true;
11162            }
11163            if (components != null) {
11164                for (int i=0; i<components.size(); i++) {
11165                    if (components.get(i).equals(comp)) {
11166                        return true;
11167                    }
11168                }
11169            }
11170            if (objects != null) {
11171                for (int i=0; i<objects.size(); i++) {
11172                    if (System.identityHashCode(object) == objects.get(i)) {
11173                        return true;
11174                    }
11175                }
11176            }
11177            if (strings != null) {
11178                String flat = comp.flattenToString();
11179                for (int i=0; i<strings.size(); i++) {
11180                    if (flat.contains(strings.get(i))) {
11181                        return true;
11182                    }
11183                }
11184            }
11185            return false;
11186        }
11187    }
11188
11189    /**
11190     * There are three things that cmd can be:
11191     *  - a flattened component name that matches an existing activity
11192     *  - the cmd arg isn't the flattened component name of an existing activity:
11193     *    dump all activity whose component contains the cmd as a substring
11194     *  - A hex number of the ActivityRecord object instance.
11195     */
11196    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11197            int opti, boolean dumpAll) {
11198        ArrayList<ActivityRecord> activities;
11199
11200        synchronized (this) {
11201            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11202        }
11203
11204        if (activities.size() <= 0) {
11205            return false;
11206        }
11207
11208        String[] newArgs = new String[args.length - opti];
11209        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11210
11211        TaskRecord lastTask = null;
11212        boolean needSep = false;
11213        for (int i=activities.size()-1; i>=0; i--) {
11214            ActivityRecord r = activities.get(i);
11215            if (needSep) {
11216                pw.println();
11217            }
11218            needSep = true;
11219            synchronized (this) {
11220                if (lastTask != r.task) {
11221                    lastTask = r.task;
11222                    pw.print("TASK "); pw.print(lastTask.affinity);
11223                            pw.print(" id="); pw.println(lastTask.taskId);
11224                    if (dumpAll) {
11225                        lastTask.dump(pw, "  ");
11226                    }
11227                }
11228            }
11229            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11230        }
11231        return true;
11232    }
11233
11234    /**
11235     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11236     * there is a thread associated with the activity.
11237     */
11238    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11239            final ActivityRecord r, String[] args, boolean dumpAll) {
11240        String innerPrefix = prefix + "  ";
11241        synchronized (this) {
11242            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11243                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11244                    pw.print(" pid=");
11245                    if (r.app != null) pw.println(r.app.pid);
11246                    else pw.println("(not running)");
11247            if (dumpAll) {
11248                r.dump(pw, innerPrefix);
11249            }
11250        }
11251        if (r.app != null && r.app.thread != null) {
11252            // flush anything that is already in the PrintWriter since the thread is going
11253            // to write to the file descriptor directly
11254            pw.flush();
11255            try {
11256                TransferPipe tp = new TransferPipe();
11257                try {
11258                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11259                            r.appToken, innerPrefix, args);
11260                    tp.go(fd);
11261                } finally {
11262                    tp.kill();
11263                }
11264            } catch (IOException e) {
11265                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11266            } catch (RemoteException e) {
11267                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11268            }
11269        }
11270    }
11271
11272    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11273            int opti, boolean dumpAll, String dumpPackage) {
11274        boolean needSep = false;
11275        boolean onlyHistory = false;
11276        boolean printedAnything = false;
11277
11278        if ("history".equals(dumpPackage)) {
11279            if (opti < args.length && "-s".equals(args[opti])) {
11280                dumpAll = false;
11281            }
11282            onlyHistory = true;
11283            dumpPackage = null;
11284        }
11285
11286        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11287        if (!onlyHistory && dumpAll) {
11288            if (mRegisteredReceivers.size() > 0) {
11289                boolean printed = false;
11290                Iterator it = mRegisteredReceivers.values().iterator();
11291                while (it.hasNext()) {
11292                    ReceiverList r = (ReceiverList)it.next();
11293                    if (dumpPackage != null && (r.app == null ||
11294                            !dumpPackage.equals(r.app.info.packageName))) {
11295                        continue;
11296                    }
11297                    if (!printed) {
11298                        pw.println("  Registered Receivers:");
11299                        needSep = true;
11300                        printed = true;
11301                        printedAnything = true;
11302                    }
11303                    pw.print("  * "); pw.println(r);
11304                    r.dump(pw, "    ");
11305                }
11306            }
11307
11308            if (mReceiverResolver.dump(pw, needSep ?
11309                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11310                    "    ", dumpPackage, false)) {
11311                needSep = true;
11312                printedAnything = true;
11313            }
11314        }
11315
11316        for (BroadcastQueue q : mBroadcastQueues) {
11317            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11318            printedAnything |= needSep;
11319        }
11320
11321        needSep = true;
11322
11323        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11324            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11325                if (needSep) {
11326                    pw.println();
11327                }
11328                needSep = true;
11329                printedAnything = true;
11330                pw.print("  Sticky broadcasts for user ");
11331                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11332                StringBuilder sb = new StringBuilder(128);
11333                for (Map.Entry<String, ArrayList<Intent>> ent
11334                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11335                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11336                    if (dumpAll) {
11337                        pw.println(":");
11338                        ArrayList<Intent> intents = ent.getValue();
11339                        final int N = intents.size();
11340                        for (int i=0; i<N; i++) {
11341                            sb.setLength(0);
11342                            sb.append("    Intent: ");
11343                            intents.get(i).toShortString(sb, false, true, false, false);
11344                            pw.println(sb.toString());
11345                            Bundle bundle = intents.get(i).getExtras();
11346                            if (bundle != null) {
11347                                pw.print("      ");
11348                                pw.println(bundle.toString());
11349                            }
11350                        }
11351                    } else {
11352                        pw.println("");
11353                    }
11354                }
11355            }
11356        }
11357
11358        if (!onlyHistory && dumpAll) {
11359            pw.println();
11360            for (BroadcastQueue queue : mBroadcastQueues) {
11361                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11362                        + queue.mBroadcastsScheduled);
11363            }
11364            pw.println("  mHandler:");
11365            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11366            needSep = true;
11367            printedAnything = true;
11368        }
11369
11370        if (!printedAnything) {
11371            pw.println("  (nothing)");
11372        }
11373    }
11374
11375    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11376            int opti, boolean dumpAll, String dumpPackage) {
11377        boolean needSep;
11378        boolean printedAnything = false;
11379
11380        ItemMatcher matcher = new ItemMatcher();
11381        matcher.build(args, opti);
11382
11383        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
11384
11385        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
11386        printedAnything |= needSep;
11387
11388        if (mLaunchingProviders.size() > 0) {
11389            boolean printed = false;
11390            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
11391                ContentProviderRecord r = mLaunchingProviders.get(i);
11392                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
11393                    continue;
11394                }
11395                if (!printed) {
11396                    if (needSep) pw.println();
11397                    needSep = true;
11398                    pw.println("  Launching content providers:");
11399                    printed = true;
11400                    printedAnything = true;
11401                }
11402                pw.print("  Launching #"); pw.print(i); pw.print(": ");
11403                        pw.println(r);
11404            }
11405        }
11406
11407        if (mGrantedUriPermissions.size() > 0) {
11408            boolean printed = false;
11409            int dumpUid = -2;
11410            if (dumpPackage != null) {
11411                try {
11412                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
11413                } catch (NameNotFoundException e) {
11414                    dumpUid = -1;
11415                }
11416            }
11417            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
11418                int uid = mGrantedUriPermissions.keyAt(i);
11419                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
11420                    continue;
11421                }
11422                ArrayMap<Uri, UriPermission> perms
11423                        = mGrantedUriPermissions.valueAt(i);
11424                if (!printed) {
11425                    if (needSep) pw.println();
11426                    needSep = true;
11427                    pw.println("  Granted Uri Permissions:");
11428                    printed = true;
11429                    printedAnything = true;
11430                }
11431                pw.print("  * UID "); pw.print(uid);
11432                        pw.println(" holds:");
11433                for (UriPermission perm : perms.values()) {
11434                    pw.print("    "); pw.println(perm);
11435                    if (dumpAll) {
11436                        perm.dump(pw, "      ");
11437                    }
11438                }
11439            }
11440        }
11441
11442        if (!printedAnything) {
11443            pw.println("  (nothing)");
11444        }
11445    }
11446
11447    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11448            int opti, boolean dumpAll, String dumpPackage) {
11449        boolean printed = false;
11450
11451        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
11452
11453        if (mIntentSenderRecords.size() > 0) {
11454            Iterator<WeakReference<PendingIntentRecord>> it
11455                    = mIntentSenderRecords.values().iterator();
11456            while (it.hasNext()) {
11457                WeakReference<PendingIntentRecord> ref = it.next();
11458                PendingIntentRecord rec = ref != null ? ref.get(): null;
11459                if (dumpPackage != null && (rec == null
11460                        || !dumpPackage.equals(rec.key.packageName))) {
11461                    continue;
11462                }
11463                printed = true;
11464                if (rec != null) {
11465                    pw.print("  * "); pw.println(rec);
11466                    if (dumpAll) {
11467                        rec.dump(pw, "    ");
11468                    }
11469                } else {
11470                    pw.print("  * "); pw.println(ref);
11471                }
11472            }
11473        }
11474
11475        if (!printed) {
11476            pw.println("  (nothing)");
11477        }
11478    }
11479
11480    private static final int dumpProcessList(PrintWriter pw,
11481            ActivityManagerService service, List list,
11482            String prefix, String normalLabel, String persistentLabel,
11483            String dumpPackage) {
11484        int numPers = 0;
11485        final int N = list.size()-1;
11486        for (int i=N; i>=0; i--) {
11487            ProcessRecord r = (ProcessRecord)list.get(i);
11488            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
11489                continue;
11490            }
11491            pw.println(String.format("%s%s #%2d: %s",
11492                    prefix, (r.persistent ? persistentLabel : normalLabel),
11493                    i, r.toString()));
11494            if (r.persistent) {
11495                numPers++;
11496            }
11497        }
11498        return numPers;
11499    }
11500
11501    private static final boolean dumpProcessOomList(PrintWriter pw,
11502            ActivityManagerService service, List<ProcessRecord> origList,
11503            String prefix, String normalLabel, String persistentLabel,
11504            boolean inclDetails, String dumpPackage) {
11505
11506        ArrayList<Pair<ProcessRecord, Integer>> list
11507                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
11508        for (int i=0; i<origList.size(); i++) {
11509            ProcessRecord r = origList.get(i);
11510            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11511                continue;
11512            }
11513            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
11514        }
11515
11516        if (list.size() <= 0) {
11517            return false;
11518        }
11519
11520        Comparator<Pair<ProcessRecord, Integer>> comparator
11521                = new Comparator<Pair<ProcessRecord, Integer>>() {
11522            @Override
11523            public int compare(Pair<ProcessRecord, Integer> object1,
11524                    Pair<ProcessRecord, Integer> object2) {
11525                if (object1.first.setAdj != object2.first.setAdj) {
11526                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
11527                }
11528                if (object1.second.intValue() != object2.second.intValue()) {
11529                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
11530                }
11531                return 0;
11532            }
11533        };
11534
11535        Collections.sort(list, comparator);
11536
11537        final long curRealtime = SystemClock.elapsedRealtime();
11538        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
11539        final long curUptime = SystemClock.uptimeMillis();
11540        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
11541
11542        for (int i=list.size()-1; i>=0; i--) {
11543            ProcessRecord r = list.get(i).first;
11544            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
11545            char schedGroup;
11546            switch (r.setSchedGroup) {
11547                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
11548                    schedGroup = 'B';
11549                    break;
11550                case Process.THREAD_GROUP_DEFAULT:
11551                    schedGroup = 'F';
11552                    break;
11553                default:
11554                    schedGroup = '?';
11555                    break;
11556            }
11557            char foreground;
11558            if (r.foregroundActivities) {
11559                foreground = 'A';
11560            } else if (r.foregroundServices) {
11561                foreground = 'S';
11562            } else {
11563                foreground = ' ';
11564            }
11565            String procState = ProcessList.makeProcStateString(r.curProcState);
11566            pw.print(prefix);
11567            pw.print(r.persistent ? persistentLabel : normalLabel);
11568            pw.print(" #");
11569            int num = (origList.size()-1)-list.get(i).second;
11570            if (num < 10) pw.print(' ');
11571            pw.print(num);
11572            pw.print(": ");
11573            pw.print(oomAdj);
11574            pw.print(' ');
11575            pw.print(schedGroup);
11576            pw.print('/');
11577            pw.print(foreground);
11578            pw.print('/');
11579            pw.print(procState);
11580            pw.print(" trm:");
11581            if (r.trimMemoryLevel < 10) pw.print(' ');
11582            pw.print(r.trimMemoryLevel);
11583            pw.print(' ');
11584            pw.print(r.toShortString());
11585            pw.print(" (");
11586            pw.print(r.adjType);
11587            pw.println(')');
11588            if (r.adjSource != null || r.adjTarget != null) {
11589                pw.print(prefix);
11590                pw.print("    ");
11591                if (r.adjTarget instanceof ComponentName) {
11592                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
11593                } else if (r.adjTarget != null) {
11594                    pw.print(r.adjTarget.toString());
11595                } else {
11596                    pw.print("{null}");
11597                }
11598                pw.print("<=");
11599                if (r.adjSource instanceof ProcessRecord) {
11600                    pw.print("Proc{");
11601                    pw.print(((ProcessRecord)r.adjSource).toShortString());
11602                    pw.println("}");
11603                } else if (r.adjSource != null) {
11604                    pw.println(r.adjSource.toString());
11605                } else {
11606                    pw.println("{null}");
11607                }
11608            }
11609            if (inclDetails) {
11610                pw.print(prefix);
11611                pw.print("    ");
11612                pw.print("oom: max="); pw.print(r.maxAdj);
11613                pw.print(" curRaw="); pw.print(r.curRawAdj);
11614                pw.print(" setRaw="); pw.print(r.setRawAdj);
11615                pw.print(" cur="); pw.print(r.curAdj);
11616                pw.print(" set="); pw.println(r.setAdj);
11617                pw.print(prefix);
11618                pw.print("    ");
11619                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
11620                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
11621                pw.print(" lastPss="); pw.print(r.lastPss);
11622                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
11623                pw.print(prefix);
11624                pw.print("    ");
11625                pw.print("keeping="); pw.print(r.keeping);
11626                pw.print(" cached="); pw.print(r.cached);
11627                pw.print(" empty="); pw.print(r.empty);
11628                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
11629
11630                if (!r.keeping) {
11631                    if (r.lastWakeTime != 0) {
11632                        long wtime;
11633                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
11634                        synchronized (stats) {
11635                            wtime = stats.getProcessWakeTime(r.info.uid,
11636                                    r.pid, curRealtime);
11637                        }
11638                        long timeUsed = wtime - r.lastWakeTime;
11639                        pw.print(prefix);
11640                        pw.print("    ");
11641                        pw.print("keep awake over ");
11642                        TimeUtils.formatDuration(realtimeSince, pw);
11643                        pw.print(" used ");
11644                        TimeUtils.formatDuration(timeUsed, pw);
11645                        pw.print(" (");
11646                        pw.print((timeUsed*100)/realtimeSince);
11647                        pw.println("%)");
11648                    }
11649                    if (r.lastCpuTime != 0) {
11650                        long timeUsed = r.curCpuTime - r.lastCpuTime;
11651                        pw.print(prefix);
11652                        pw.print("    ");
11653                        pw.print("run cpu over ");
11654                        TimeUtils.formatDuration(uptimeSince, pw);
11655                        pw.print(" used ");
11656                        TimeUtils.formatDuration(timeUsed, pw);
11657                        pw.print(" (");
11658                        pw.print((timeUsed*100)/uptimeSince);
11659                        pw.println("%)");
11660                    }
11661                }
11662            }
11663        }
11664        return true;
11665    }
11666
11667    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
11668        ArrayList<ProcessRecord> procs;
11669        synchronized (this) {
11670            if (args != null && args.length > start
11671                    && args[start].charAt(0) != '-') {
11672                procs = new ArrayList<ProcessRecord>();
11673                int pid = -1;
11674                try {
11675                    pid = Integer.parseInt(args[start]);
11676                } catch (NumberFormatException e) {
11677                }
11678                for (int i=mLruProcesses.size()-1; i>=0; i--) {
11679                    ProcessRecord proc = mLruProcesses.get(i);
11680                    if (proc.pid == pid) {
11681                        procs.add(proc);
11682                    } else if (proc.processName.equals(args[start])) {
11683                        procs.add(proc);
11684                    }
11685                }
11686                if (procs.size() <= 0) {
11687                    return null;
11688                }
11689            } else {
11690                procs = new ArrayList<ProcessRecord>(mLruProcesses);
11691            }
11692        }
11693        return procs;
11694    }
11695
11696    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
11697            PrintWriter pw, String[] args) {
11698        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11699        if (procs == null) {
11700            pw.println("No process found for: " + args[0]);
11701            return;
11702        }
11703
11704        long uptime = SystemClock.uptimeMillis();
11705        long realtime = SystemClock.elapsedRealtime();
11706        pw.println("Applications Graphics Acceleration Info:");
11707        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11708
11709        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11710            ProcessRecord r = procs.get(i);
11711            if (r.thread != null) {
11712                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
11713                pw.flush();
11714                try {
11715                    TransferPipe tp = new TransferPipe();
11716                    try {
11717                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
11718                        tp.go(fd);
11719                    } finally {
11720                        tp.kill();
11721                    }
11722                } catch (IOException e) {
11723                    pw.println("Failure while dumping the app: " + r);
11724                    pw.flush();
11725                } catch (RemoteException e) {
11726                    pw.println("Got a RemoteException while dumping the app " + r);
11727                    pw.flush();
11728                }
11729            }
11730        }
11731    }
11732
11733    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
11734        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
11735        if (procs == null) {
11736            pw.println("No process found for: " + args[0]);
11737            return;
11738        }
11739
11740        pw.println("Applications Database Info:");
11741
11742        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
11743            ProcessRecord r = procs.get(i);
11744            if (r.thread != null) {
11745                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
11746                pw.flush();
11747                try {
11748                    TransferPipe tp = new TransferPipe();
11749                    try {
11750                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
11751                        tp.go(fd);
11752                    } finally {
11753                        tp.kill();
11754                    }
11755                } catch (IOException e) {
11756                    pw.println("Failure while dumping the app: " + r);
11757                    pw.flush();
11758                } catch (RemoteException e) {
11759                    pw.println("Got a RemoteException while dumping the app " + r);
11760                    pw.flush();
11761                }
11762            }
11763        }
11764    }
11765
11766    final static class MemItem {
11767        final boolean isProc;
11768        final String label;
11769        final String shortLabel;
11770        final long pss;
11771        final int id;
11772        final boolean hasActivities;
11773        ArrayList<MemItem> subitems;
11774
11775        public MemItem(String _label, String _shortLabel, long _pss, int _id,
11776                boolean _hasActivities) {
11777            isProc = true;
11778            label = _label;
11779            shortLabel = _shortLabel;
11780            pss = _pss;
11781            id = _id;
11782            hasActivities = _hasActivities;
11783        }
11784
11785        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
11786            isProc = false;
11787            label = _label;
11788            shortLabel = _shortLabel;
11789            pss = _pss;
11790            id = _id;
11791            hasActivities = false;
11792        }
11793    }
11794
11795    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
11796            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
11797        if (sort && !isCompact) {
11798            Collections.sort(items, new Comparator<MemItem>() {
11799                @Override
11800                public int compare(MemItem lhs, MemItem rhs) {
11801                    if (lhs.pss < rhs.pss) {
11802                        return 1;
11803                    } else if (lhs.pss > rhs.pss) {
11804                        return -1;
11805                    }
11806                    return 0;
11807                }
11808            });
11809        }
11810
11811        for (int i=0; i<items.size(); i++) {
11812            MemItem mi = items.get(i);
11813            if (!isCompact) {
11814                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
11815            } else if (mi.isProc) {
11816                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
11817                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
11818                pw.println(mi.hasActivities ? ",a" : ",e");
11819            } else {
11820                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
11821                pw.println(mi.pss);
11822            }
11823            if (mi.subitems != null) {
11824                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
11825                        true, isCompact);
11826            }
11827        }
11828    }
11829
11830    // These are in KB.
11831    static final long[] DUMP_MEM_BUCKETS = new long[] {
11832        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
11833        120*1024, 160*1024, 200*1024,
11834        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
11835        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
11836    };
11837
11838    static final void appendMemBucket(StringBuilder out, long memKB, String label,
11839            boolean stackLike) {
11840        int start = label.lastIndexOf('.');
11841        if (start >= 0) start++;
11842        else start = 0;
11843        int end = label.length();
11844        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
11845            if (DUMP_MEM_BUCKETS[i] >= memKB) {
11846                long bucket = DUMP_MEM_BUCKETS[i]/1024;
11847                out.append(bucket);
11848                out.append(stackLike ? "MB." : "MB ");
11849                out.append(label, start, end);
11850                return;
11851            }
11852        }
11853        out.append(memKB/1024);
11854        out.append(stackLike ? "MB." : "MB ");
11855        out.append(label, start, end);
11856    }
11857
11858    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
11859            ProcessList.NATIVE_ADJ,
11860            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
11861            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
11862            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
11863            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
11864            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
11865    };
11866    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
11867            "Native",
11868            "System", "Persistent", "Foreground",
11869            "Visible", "Perceptible",
11870            "Heavy Weight", "Backup",
11871            "A Services", "Home",
11872            "Previous", "B Services", "Cached"
11873    };
11874    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
11875            "native",
11876            "sys", "pers", "fore",
11877            "vis", "percept",
11878            "heavy", "backup",
11879            "servicea", "home",
11880            "prev", "serviceb", "cached"
11881    };
11882
11883    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
11884            long realtime, boolean isCheckinRequest, boolean isCompact) {
11885        if (isCheckinRequest || isCompact) {
11886            // short checkin version
11887            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
11888        } else {
11889            pw.println("Applications Memory Usage (kB):");
11890            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
11891        }
11892    }
11893
11894    final void dumpApplicationMemoryUsage(FileDescriptor fd,
11895            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
11896        boolean dumpDetails = false;
11897        boolean dumpFullDetails = false;
11898        boolean dumpDalvik = false;
11899        boolean oomOnly = false;
11900        boolean isCompact = false;
11901        boolean localOnly = false;
11902
11903        int opti = 0;
11904        while (opti < args.length) {
11905            String opt = args[opti];
11906            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11907                break;
11908            }
11909            opti++;
11910            if ("-a".equals(opt)) {
11911                dumpDetails = true;
11912                dumpFullDetails = true;
11913                dumpDalvik = true;
11914            } else if ("-d".equals(opt)) {
11915                dumpDalvik = true;
11916            } else if ("-c".equals(opt)) {
11917                isCompact = true;
11918            } else if ("--oom".equals(opt)) {
11919                oomOnly = true;
11920            } else if ("--local".equals(opt)) {
11921                localOnly = true;
11922            } else if ("-h".equals(opt)) {
11923                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
11924                pw.println("  -a: include all available information for each process.");
11925                pw.println("  -d: include dalvik details when dumping process details.");
11926                pw.println("  -c: dump in a compact machine-parseable representation.");
11927                pw.println("  --oom: only show processes organized by oom adj.");
11928                pw.println("  --local: only collect details locally, don't call process.");
11929                pw.println("If [process] is specified it can be the name or ");
11930                pw.println("pid of a specific process to dump.");
11931                return;
11932            } else {
11933                pw.println("Unknown argument: " + opt + "; use -h for help");
11934            }
11935        }
11936
11937        final boolean isCheckinRequest = scanArgs(args, "--checkin");
11938        long uptime = SystemClock.uptimeMillis();
11939        long realtime = SystemClock.elapsedRealtime();
11940        final long[] tmpLong = new long[1];
11941
11942        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
11943        if (procs == null) {
11944            // No Java processes.  Maybe they want to print a native process.
11945            if (args != null && args.length > opti
11946                    && args[opti].charAt(0) != '-') {
11947                ArrayList<ProcessCpuTracker.Stats> nativeProcs
11948                        = new ArrayList<ProcessCpuTracker.Stats>();
11949                updateCpuStatsNow();
11950                int findPid = -1;
11951                try {
11952                    findPid = Integer.parseInt(args[opti]);
11953                } catch (NumberFormatException e) {
11954                }
11955                synchronized (mProcessCpuThread) {
11956                    final int N = mProcessCpuTracker.countStats();
11957                    for (int i=0; i<N; i++) {
11958                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
11959                        if (st.pid == findPid || (st.baseName != null
11960                                && st.baseName.equals(args[opti]))) {
11961                            nativeProcs.add(st);
11962                        }
11963                    }
11964                }
11965                if (nativeProcs.size() > 0) {
11966                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
11967                            isCompact);
11968                    Debug.MemoryInfo mi = null;
11969                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
11970                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
11971                        final int pid = r.pid;
11972                        if (!isCheckinRequest && dumpDetails) {
11973                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
11974                        }
11975                        if (mi == null) {
11976                            mi = new Debug.MemoryInfo();
11977                        }
11978                        if (dumpDetails || (!brief && !oomOnly)) {
11979                            Debug.getMemoryInfo(pid, mi);
11980                        } else {
11981                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
11982                            mi.dalvikPrivateDirty = (int)tmpLong[0];
11983                        }
11984                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
11985                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
11986                        if (isCheckinRequest) {
11987                            pw.println();
11988                        }
11989                    }
11990                    return;
11991                }
11992            }
11993            pw.println("No process found for: " + args[opti]);
11994            return;
11995        }
11996
11997        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
11998            dumpDetails = true;
11999        }
12000
12001        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12002
12003        String[] innerArgs = new String[args.length-opti];
12004        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12005
12006        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12007        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12008        long nativePss=0, dalvikPss=0, otherPss=0;
12009        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12010
12011        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12012        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12013                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12014
12015        long totalPss = 0;
12016        long cachedPss = 0;
12017
12018        Debug.MemoryInfo mi = null;
12019        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12020            final ProcessRecord r = procs.get(i);
12021            final IApplicationThread thread;
12022            final int pid;
12023            final int oomAdj;
12024            final boolean hasActivities;
12025            synchronized (this) {
12026                thread = r.thread;
12027                pid = r.pid;
12028                oomAdj = r.getSetAdjWithServices();
12029                hasActivities = r.activities.size() > 0;
12030            }
12031            if (thread != null) {
12032                if (!isCheckinRequest && dumpDetails) {
12033                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12034                }
12035                if (mi == null) {
12036                    mi = new Debug.MemoryInfo();
12037                }
12038                if (dumpDetails || (!brief && !oomOnly)) {
12039                    Debug.getMemoryInfo(pid, mi);
12040                } else {
12041                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12042                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12043                }
12044                if (dumpDetails) {
12045                    if (localOnly) {
12046                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12047                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12048                        if (isCheckinRequest) {
12049                            pw.println();
12050                        }
12051                    } else {
12052                        try {
12053                            pw.flush();
12054                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12055                                    dumpDalvik, innerArgs);
12056                        } catch (RemoteException e) {
12057                            if (!isCheckinRequest) {
12058                                pw.println("Got RemoteException!");
12059                                pw.flush();
12060                            }
12061                        }
12062                    }
12063                }
12064
12065                final long myTotalPss = mi.getTotalPss();
12066                final long myTotalUss = mi.getTotalUss();
12067
12068                synchronized (this) {
12069                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12070                        // Record this for posterity if the process has been stable.
12071                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12072                    }
12073                }
12074
12075                if (!isCheckinRequest && mi != null) {
12076                    totalPss += myTotalPss;
12077                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12078                            (hasActivities ? " / activities)" : ")"),
12079                            r.processName, myTotalPss, pid, hasActivities);
12080                    procMems.add(pssItem);
12081                    procMemsMap.put(pid, pssItem);
12082
12083                    nativePss += mi.nativePss;
12084                    dalvikPss += mi.dalvikPss;
12085                    otherPss += mi.otherPss;
12086                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12087                        long mem = mi.getOtherPss(j);
12088                        miscPss[j] += mem;
12089                        otherPss -= mem;
12090                    }
12091
12092                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12093                        cachedPss += myTotalPss;
12094                    }
12095
12096                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12097                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12098                                || oomIndex == (oomPss.length-1)) {
12099                            oomPss[oomIndex] += myTotalPss;
12100                            if (oomProcs[oomIndex] == null) {
12101                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12102                            }
12103                            oomProcs[oomIndex].add(pssItem);
12104                            break;
12105                        }
12106                    }
12107                }
12108            }
12109        }
12110
12111        if (!isCheckinRequest && procs.size() > 1) {
12112            // If we are showing aggregations, also look for native processes to
12113            // include so that our aggregations are more accurate.
12114            updateCpuStatsNow();
12115            synchronized (mProcessCpuThread) {
12116                final int N = mProcessCpuTracker.countStats();
12117                for (int i=0; i<N; i++) {
12118                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12119                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12120                        if (mi == null) {
12121                            mi = new Debug.MemoryInfo();
12122                        }
12123                        if (!brief && !oomOnly) {
12124                            Debug.getMemoryInfo(st.pid, mi);
12125                        } else {
12126                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12127                            mi.nativePrivateDirty = (int)tmpLong[0];
12128                        }
12129
12130                        final long myTotalPss = mi.getTotalPss();
12131                        totalPss += myTotalPss;
12132
12133                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12134                                st.name, myTotalPss, st.pid, false);
12135                        procMems.add(pssItem);
12136
12137                        nativePss += mi.nativePss;
12138                        dalvikPss += mi.dalvikPss;
12139                        otherPss += mi.otherPss;
12140                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12141                            long mem = mi.getOtherPss(j);
12142                            miscPss[j] += mem;
12143                            otherPss -= mem;
12144                        }
12145                        oomPss[0] += myTotalPss;
12146                        if (oomProcs[0] == null) {
12147                            oomProcs[0] = new ArrayList<MemItem>();
12148                        }
12149                        oomProcs[0].add(pssItem);
12150                    }
12151                }
12152            }
12153
12154            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12155
12156            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12157            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12158            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12159            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12160                String label = Debug.MemoryInfo.getOtherLabel(j);
12161                catMems.add(new MemItem(label, label, miscPss[j], j));
12162            }
12163
12164            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12165            for (int j=0; j<oomPss.length; j++) {
12166                if (oomPss[j] != 0) {
12167                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12168                            : DUMP_MEM_OOM_LABEL[j];
12169                    MemItem item = new MemItem(label, label, oomPss[j],
12170                            DUMP_MEM_OOM_ADJ[j]);
12171                    item.subitems = oomProcs[j];
12172                    oomMems.add(item);
12173                }
12174            }
12175
12176            if (!brief && !oomOnly && !isCompact) {
12177                pw.println();
12178                pw.println("Total PSS by process:");
12179                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12180                pw.println();
12181            }
12182            if (!isCompact) {
12183                pw.println("Total PSS by OOM adjustment:");
12184            }
12185            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12186            if (!brief && !oomOnly) {
12187                PrintWriter out = categoryPw != null ? categoryPw : pw;
12188                if (!isCompact) {
12189                    out.println();
12190                    out.println("Total PSS by category:");
12191                }
12192                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12193            }
12194            if (!isCompact) {
12195                pw.println();
12196            }
12197            MemInfoReader memInfo = new MemInfoReader();
12198            memInfo.readMemInfo();
12199            if (!brief) {
12200                if (!isCompact) {
12201                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12202                    pw.print(" kB (status ");
12203                    switch (mLastMemoryLevel) {
12204                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12205                            pw.println("normal)");
12206                            break;
12207                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12208                            pw.println("moderate)");
12209                            break;
12210                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12211                            pw.println("low)");
12212                            break;
12213                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12214                            pw.println("critical)");
12215                            break;
12216                        default:
12217                            pw.print(mLastMemoryLevel);
12218                            pw.println(")");
12219                            break;
12220                    }
12221                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12222                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12223                            pw.print(cachedPss); pw.print(" cached pss + ");
12224                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12225                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12226                } else {
12227                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12228                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12229                            + memInfo.getFreeSizeKb()); pw.print(",");
12230                    pw.println(totalPss - cachedPss);
12231                }
12232            }
12233            if (!isCompact) {
12234                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12235                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12236                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12237                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12238                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12239                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12240                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12241                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12242                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12243                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12244                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12245            }
12246            if (!brief) {
12247                if (memInfo.getZramTotalSizeKb() != 0) {
12248                    if (!isCompact) {
12249                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12250                                pw.print(" kB physical used for ");
12251                                pw.print(memInfo.getSwapTotalSizeKb()
12252                                        - memInfo.getSwapFreeSizeKb());
12253                                pw.print(" kB in swap (");
12254                                pw.print(memInfo.getSwapTotalSizeKb());
12255                                pw.println(" kB total swap)");
12256                    } else {
12257                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12258                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12259                                pw.println(memInfo.getSwapFreeSizeKb());
12260                    }
12261                }
12262                final int[] SINGLE_LONG_FORMAT = new int[] {
12263                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12264                };
12265                long[] longOut = new long[1];
12266                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12267                        SINGLE_LONG_FORMAT, null, longOut, null);
12268                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12269                longOut[0] = 0;
12270                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12271                        SINGLE_LONG_FORMAT, null, longOut, null);
12272                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12273                longOut[0] = 0;
12274                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12275                        SINGLE_LONG_FORMAT, null, longOut, null);
12276                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12277                longOut[0] = 0;
12278                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12279                        SINGLE_LONG_FORMAT, null, longOut, null);
12280                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12281                if (!isCompact) {
12282                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12283                        pw.print("      KSM: "); pw.print(sharing);
12284                                pw.print(" kB saved from shared ");
12285                                pw.print(shared); pw.println(" kB");
12286                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12287                                pw.print(voltile); pw.println(" kB volatile");
12288                    }
12289                    pw.print("   Tuning: ");
12290                    pw.print(ActivityManager.staticGetMemoryClass());
12291                    pw.print(" (large ");
12292                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12293                    pw.print("), oom ");
12294                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12295                    pw.print(" kB");
12296                    pw.print(", restore limit ");
12297                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12298                    pw.print(" kB");
12299                    if (ActivityManager.isLowRamDeviceStatic()) {
12300                        pw.print(" (low-ram)");
12301                    }
12302                    if (ActivityManager.isHighEndGfx()) {
12303                        pw.print(" (high-end-gfx)");
12304                    }
12305                    pw.println();
12306                } else {
12307                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12308                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12309                    pw.println(voltile);
12310                    pw.print("tuning,");
12311                    pw.print(ActivityManager.staticGetMemoryClass());
12312                    pw.print(',');
12313                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12314                    pw.print(',');
12315                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12316                    if (ActivityManager.isLowRamDeviceStatic()) {
12317                        pw.print(",low-ram");
12318                    }
12319                    if (ActivityManager.isHighEndGfx()) {
12320                        pw.print(",high-end-gfx");
12321                    }
12322                    pw.println();
12323                }
12324            }
12325        }
12326    }
12327
12328    /**
12329     * Searches array of arguments for the specified string
12330     * @param args array of argument strings
12331     * @param value value to search for
12332     * @return true if the value is contained in the array
12333     */
12334    private static boolean scanArgs(String[] args, String value) {
12335        if (args != null) {
12336            for (String arg : args) {
12337                if (value.equals(arg)) {
12338                    return true;
12339                }
12340            }
12341        }
12342        return false;
12343    }
12344
12345    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12346            ContentProviderRecord cpr, boolean always) {
12347        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12348
12349        if (!inLaunching || always) {
12350            synchronized (cpr) {
12351                cpr.launchingApp = null;
12352                cpr.notifyAll();
12353            }
12354            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12355            String names[] = cpr.info.authority.split(";");
12356            for (int j = 0; j < names.length; j++) {
12357                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12358            }
12359        }
12360
12361        for (int i=0; i<cpr.connections.size(); i++) {
12362            ContentProviderConnection conn = cpr.connections.get(i);
12363            if (conn.waiting) {
12364                // If this connection is waiting for the provider, then we don't
12365                // need to mess with its process unless we are always removing
12366                // or for some reason the provider is not currently launching.
12367                if (inLaunching && !always) {
12368                    continue;
12369                }
12370            }
12371            ProcessRecord capp = conn.client;
12372            conn.dead = true;
12373            if (conn.stableCount > 0) {
12374                if (!capp.persistent && capp.thread != null
12375                        && capp.pid != 0
12376                        && capp.pid != MY_PID) {
12377                    killUnneededProcessLocked(capp, "depends on provider "
12378                            + cpr.name.flattenToShortString()
12379                            + " in dying proc " + (proc != null ? proc.processName : "??"));
12380                }
12381            } else if (capp.thread != null && conn.provider.provider != null) {
12382                try {
12383                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
12384                } catch (RemoteException e) {
12385                }
12386                // In the protocol here, we don't expect the client to correctly
12387                // clean up this connection, we'll just remove it.
12388                cpr.connections.remove(i);
12389                conn.client.conProviders.remove(conn);
12390            }
12391        }
12392
12393        if (inLaunching && always) {
12394            mLaunchingProviders.remove(cpr);
12395        }
12396        return inLaunching;
12397    }
12398
12399    /**
12400     * Main code for cleaning up a process when it has gone away.  This is
12401     * called both as a result of the process dying, or directly when stopping
12402     * a process when running in single process mode.
12403     */
12404    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
12405            boolean restarting, boolean allowRestart, int index) {
12406        if (index >= 0) {
12407            removeLruProcessLocked(app);
12408            ProcessList.remove(app.pid);
12409        }
12410
12411        mProcessesToGc.remove(app);
12412        mPendingPssProcesses.remove(app);
12413
12414        // Dismiss any open dialogs.
12415        if (app.crashDialog != null && !app.forceCrashReport) {
12416            app.crashDialog.dismiss();
12417            app.crashDialog = null;
12418        }
12419        if (app.anrDialog != null) {
12420            app.anrDialog.dismiss();
12421            app.anrDialog = null;
12422        }
12423        if (app.waitDialog != null) {
12424            app.waitDialog.dismiss();
12425            app.waitDialog = null;
12426        }
12427
12428        app.crashing = false;
12429        app.notResponding = false;
12430
12431        app.resetPackageList(mProcessStats);
12432        app.unlinkDeathRecipient();
12433        app.makeInactive(mProcessStats);
12434        app.forcingToForeground = null;
12435        updateProcessForegroundLocked(app, false, false);
12436        app.foregroundActivities = false;
12437        app.hasShownUi = false;
12438        app.hasAboveClient = false;
12439
12440        mServices.killServicesLocked(app, allowRestart);
12441
12442        boolean restart = false;
12443
12444        // Remove published content providers.
12445        for (int i=app.pubProviders.size()-1; i>=0; i--) {
12446            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
12447            final boolean always = app.bad || !allowRestart;
12448            if (removeDyingProviderLocked(app, cpr, always) || always) {
12449                // We left the provider in the launching list, need to
12450                // restart it.
12451                restart = true;
12452            }
12453
12454            cpr.provider = null;
12455            cpr.proc = null;
12456        }
12457        app.pubProviders.clear();
12458
12459        // Take care of any launching providers waiting for this process.
12460        if (checkAppInLaunchingProvidersLocked(app, false)) {
12461            restart = true;
12462        }
12463
12464        // Unregister from connected content providers.
12465        if (!app.conProviders.isEmpty()) {
12466            for (int i=0; i<app.conProviders.size(); i++) {
12467                ContentProviderConnection conn = app.conProviders.get(i);
12468                conn.provider.connections.remove(conn);
12469            }
12470            app.conProviders.clear();
12471        }
12472
12473        // At this point there may be remaining entries in mLaunchingProviders
12474        // where we were the only one waiting, so they are no longer of use.
12475        // Look for these and clean up if found.
12476        // XXX Commented out for now.  Trying to figure out a way to reproduce
12477        // the actual situation to identify what is actually going on.
12478        if (false) {
12479            for (int i=0; i<mLaunchingProviders.size(); i++) {
12480                ContentProviderRecord cpr = (ContentProviderRecord)
12481                        mLaunchingProviders.get(i);
12482                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
12483                    synchronized (cpr) {
12484                        cpr.launchingApp = null;
12485                        cpr.notifyAll();
12486                    }
12487                }
12488            }
12489        }
12490
12491        skipCurrentReceiverLocked(app);
12492
12493        // Unregister any receivers.
12494        for (int i=app.receivers.size()-1; i>=0; i--) {
12495            removeReceiverLocked(app.receivers.valueAt(i));
12496        }
12497        app.receivers.clear();
12498
12499        // If the app is undergoing backup, tell the backup manager about it
12500        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
12501            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
12502                    + mBackupTarget.appInfo + " died during backup");
12503            try {
12504                IBackupManager bm = IBackupManager.Stub.asInterface(
12505                        ServiceManager.getService(Context.BACKUP_SERVICE));
12506                bm.agentDisconnected(app.info.packageName);
12507            } catch (RemoteException e) {
12508                // can't happen; backup manager is local
12509            }
12510        }
12511
12512        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
12513            ProcessChangeItem item = mPendingProcessChanges.get(i);
12514            if (item.pid == app.pid) {
12515                mPendingProcessChanges.remove(i);
12516                mAvailProcessChanges.add(item);
12517            }
12518        }
12519        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
12520
12521        // If the caller is restarting this app, then leave it in its
12522        // current lists and let the caller take care of it.
12523        if (restarting) {
12524            return;
12525        }
12526
12527        if (!app.persistent || app.isolated) {
12528            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
12529                    "Removing non-persistent process during cleanup: " + app);
12530            mProcessNames.remove(app.processName, app.uid);
12531            mIsolatedProcesses.remove(app.uid);
12532            if (mHeavyWeightProcess == app) {
12533                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
12534                        mHeavyWeightProcess.userId, 0));
12535                mHeavyWeightProcess = null;
12536            }
12537        } else if (!app.removed) {
12538            // This app is persistent, so we need to keep its record around.
12539            // If it is not already on the pending app list, add it there
12540            // and start a new process for it.
12541            if (mPersistentStartingProcesses.indexOf(app) < 0) {
12542                mPersistentStartingProcesses.add(app);
12543                restart = true;
12544            }
12545        }
12546        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
12547                "Clean-up removing on hold: " + app);
12548        mProcessesOnHold.remove(app);
12549
12550        if (app == mHomeProcess) {
12551            mHomeProcess = null;
12552        }
12553        if (app == mPreviousProcess) {
12554            mPreviousProcess = null;
12555        }
12556
12557        if (restart && !app.isolated) {
12558            // We have components that still need to be running in the
12559            // process, so re-launch it.
12560            mProcessNames.put(app.processName, app.uid, app);
12561            startProcessLocked(app, "restart", app.processName);
12562        } else if (app.pid > 0 && app.pid != MY_PID) {
12563            // Goodbye!
12564            boolean removed;
12565            synchronized (mPidsSelfLocked) {
12566                mPidsSelfLocked.remove(app.pid);
12567                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
12568            }
12569            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
12570                    app.processName, app.info.uid);
12571            if (app.isolated) {
12572                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
12573            }
12574            app.setPid(0);
12575        }
12576    }
12577
12578    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
12579        // Look through the content providers we are waiting to have launched,
12580        // and if any run in this process then either schedule a restart of
12581        // the process or kill the client waiting for it if this process has
12582        // gone bad.
12583        int NL = mLaunchingProviders.size();
12584        boolean restart = false;
12585        for (int i=0; i<NL; i++) {
12586            ContentProviderRecord cpr = mLaunchingProviders.get(i);
12587            if (cpr.launchingApp == app) {
12588                if (!alwaysBad && !app.bad) {
12589                    restart = true;
12590                } else {
12591                    removeDyingProviderLocked(app, cpr, true);
12592                    // cpr should have been removed from mLaunchingProviders
12593                    NL = mLaunchingProviders.size();
12594                    i--;
12595                }
12596            }
12597        }
12598        return restart;
12599    }
12600
12601    // =========================================================
12602    // SERVICES
12603    // =========================================================
12604
12605    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
12606            int flags) {
12607        enforceNotIsolatedCaller("getServices");
12608        synchronized (this) {
12609            return mServices.getRunningServiceInfoLocked(maxNum, flags);
12610        }
12611    }
12612
12613    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
12614        enforceNotIsolatedCaller("getRunningServiceControlPanel");
12615        synchronized (this) {
12616            return mServices.getRunningServiceControlPanelLocked(name);
12617        }
12618    }
12619
12620    public ComponentName startService(IApplicationThread caller, Intent service,
12621            String resolvedType, int userId) {
12622        enforceNotIsolatedCaller("startService");
12623        // Refuse possible leaked file descriptors
12624        if (service != null && service.hasFileDescriptors() == true) {
12625            throw new IllegalArgumentException("File descriptors passed in Intent");
12626        }
12627
12628        if (DEBUG_SERVICE)
12629            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
12630        synchronized(this) {
12631            final int callingPid = Binder.getCallingPid();
12632            final int callingUid = Binder.getCallingUid();
12633            final long origId = Binder.clearCallingIdentity();
12634            ComponentName res = mServices.startServiceLocked(caller, service,
12635                    resolvedType, callingPid, callingUid, userId);
12636            Binder.restoreCallingIdentity(origId);
12637            return res;
12638        }
12639    }
12640
12641    ComponentName startServiceInPackage(int uid,
12642            Intent service, String resolvedType, int userId) {
12643        synchronized(this) {
12644            if (DEBUG_SERVICE)
12645                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
12646            final long origId = Binder.clearCallingIdentity();
12647            ComponentName res = mServices.startServiceLocked(null, service,
12648                    resolvedType, -1, uid, userId);
12649            Binder.restoreCallingIdentity(origId);
12650            return res;
12651        }
12652    }
12653
12654    public int stopService(IApplicationThread caller, Intent service,
12655            String resolvedType, int userId) {
12656        enforceNotIsolatedCaller("stopService");
12657        // Refuse possible leaked file descriptors
12658        if (service != null && service.hasFileDescriptors() == true) {
12659            throw new IllegalArgumentException("File descriptors passed in Intent");
12660        }
12661
12662        synchronized(this) {
12663            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
12664        }
12665    }
12666
12667    public IBinder peekService(Intent service, String resolvedType) {
12668        enforceNotIsolatedCaller("peekService");
12669        // Refuse possible leaked file descriptors
12670        if (service != null && service.hasFileDescriptors() == true) {
12671            throw new IllegalArgumentException("File descriptors passed in Intent");
12672        }
12673        synchronized(this) {
12674            return mServices.peekServiceLocked(service, resolvedType);
12675        }
12676    }
12677
12678    public boolean stopServiceToken(ComponentName className, IBinder token,
12679            int startId) {
12680        synchronized(this) {
12681            return mServices.stopServiceTokenLocked(className, token, startId);
12682        }
12683    }
12684
12685    public void setServiceForeground(ComponentName className, IBinder token,
12686            int id, Notification notification, boolean removeNotification) {
12687        synchronized(this) {
12688            mServices.setServiceForegroundLocked(className, token, id, notification,
12689                    removeNotification);
12690        }
12691    }
12692
12693    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
12694            boolean requireFull, String name, String callerPackage) {
12695        final int callingUserId = UserHandle.getUserId(callingUid);
12696        if (callingUserId != userId) {
12697            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
12698                if ((requireFull || checkComponentPermission(
12699                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12700                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
12701                        && checkComponentPermission(
12702                                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
12703                                callingPid, callingUid, -1, true)
12704                                != PackageManager.PERMISSION_GRANTED) {
12705                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
12706                        // In this case, they would like to just execute as their
12707                        // owner user instead of failing.
12708                        userId = callingUserId;
12709                    } else {
12710                        StringBuilder builder = new StringBuilder(128);
12711                        builder.append("Permission Denial: ");
12712                        builder.append(name);
12713                        if (callerPackage != null) {
12714                            builder.append(" from ");
12715                            builder.append(callerPackage);
12716                        }
12717                        builder.append(" asks to run as user ");
12718                        builder.append(userId);
12719                        builder.append(" but is calling from user ");
12720                        builder.append(UserHandle.getUserId(callingUid));
12721                        builder.append("; this requires ");
12722                        builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
12723                        if (!requireFull) {
12724                            builder.append(" or ");
12725                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
12726                        }
12727                        String msg = builder.toString();
12728                        Slog.w(TAG, msg);
12729                        throw new SecurityException(msg);
12730                    }
12731                }
12732            }
12733            if (userId == UserHandle.USER_CURRENT
12734                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
12735                // Note that we may be accessing this outside of a lock...
12736                // shouldn't be a big deal, if this is being called outside
12737                // of a locked context there is intrinsically a race with
12738                // the value the caller will receive and someone else changing it.
12739                userId = mCurrentUserId;
12740            }
12741            if (!allowAll && userId < 0) {
12742                throw new IllegalArgumentException(
12743                        "Call does not support special user #" + userId);
12744            }
12745        }
12746        return userId;
12747    }
12748
12749    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
12750            String className, int flags) {
12751        boolean result = false;
12752        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
12753            if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
12754                if (ActivityManager.checkUidPermission(
12755                        android.Manifest.permission.INTERACT_ACROSS_USERS,
12756                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
12757                    ComponentName comp = new ComponentName(aInfo.packageName, className);
12758                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
12759                            + " requests FLAG_SINGLE_USER, but app does not hold "
12760                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
12761                    Slog.w(TAG, msg);
12762                    throw new SecurityException(msg);
12763                }
12764                result = true;
12765            }
12766        } else if (componentProcessName == aInfo.packageName) {
12767            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12768        } else if ("system".equals(componentProcessName)) {
12769            result = true;
12770        }
12771        if (DEBUG_MU) {
12772            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
12773                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
12774        }
12775        return result;
12776    }
12777
12778    public int bindService(IApplicationThread caller, IBinder token,
12779            Intent service, String resolvedType,
12780            IServiceConnection connection, int flags, int userId) {
12781        enforceNotIsolatedCaller("bindService");
12782        // Refuse possible leaked file descriptors
12783        if (service != null && service.hasFileDescriptors() == true) {
12784            throw new IllegalArgumentException("File descriptors passed in Intent");
12785        }
12786
12787        synchronized(this) {
12788            return mServices.bindServiceLocked(caller, token, service, resolvedType,
12789                    connection, flags, userId);
12790        }
12791    }
12792
12793    public boolean unbindService(IServiceConnection connection) {
12794        synchronized (this) {
12795            return mServices.unbindServiceLocked(connection);
12796        }
12797    }
12798
12799    public void publishService(IBinder token, Intent intent, IBinder service) {
12800        // Refuse possible leaked file descriptors
12801        if (intent != null && intent.hasFileDescriptors() == true) {
12802            throw new IllegalArgumentException("File descriptors passed in Intent");
12803        }
12804
12805        synchronized(this) {
12806            if (!(token instanceof ServiceRecord)) {
12807                throw new IllegalArgumentException("Invalid service token");
12808            }
12809            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
12810        }
12811    }
12812
12813    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12814        // Refuse possible leaked file descriptors
12815        if (intent != null && intent.hasFileDescriptors() == true) {
12816            throw new IllegalArgumentException("File descriptors passed in Intent");
12817        }
12818
12819        synchronized(this) {
12820            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
12821        }
12822    }
12823
12824    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
12825        synchronized(this) {
12826            if (!(token instanceof ServiceRecord)) {
12827                throw new IllegalArgumentException("Invalid service token");
12828            }
12829            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
12830        }
12831    }
12832
12833    // =========================================================
12834    // BACKUP AND RESTORE
12835    // =========================================================
12836
12837    // Cause the target app to be launched if necessary and its backup agent
12838    // instantiated.  The backup agent will invoke backupAgentCreated() on the
12839    // activity manager to announce its creation.
12840    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
12841        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
12842        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
12843
12844        synchronized(this) {
12845            // !!! TODO: currently no check here that we're already bound
12846            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12847            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12848            synchronized (stats) {
12849                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12850            }
12851
12852            // Backup agent is now in use, its package can't be stopped.
12853            try {
12854                AppGlobals.getPackageManager().setPackageStoppedState(
12855                        app.packageName, false, UserHandle.getUserId(app.uid));
12856            } catch (RemoteException e) {
12857            } catch (IllegalArgumentException e) {
12858                Slog.w(TAG, "Failed trying to unstop package "
12859                        + app.packageName + ": " + e);
12860            }
12861
12862            BackupRecord r = new BackupRecord(ss, app, backupMode);
12863            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12864                    ? new ComponentName(app.packageName, app.backupAgentName)
12865                    : new ComponentName("android", "FullBackupAgent");
12866            // startProcessLocked() returns existing proc's record if it's already running
12867            ProcessRecord proc = startProcessLocked(app.processName, app,
12868                    false, 0, "backup", hostingName, false, false, false);
12869            if (proc == null) {
12870                Slog.e(TAG, "Unable to start backup agent process " + r);
12871                return false;
12872            }
12873
12874            r.app = proc;
12875            mBackupTarget = r;
12876            mBackupAppName = app.packageName;
12877
12878            // Try not to kill the process during backup
12879            updateOomAdjLocked(proc);
12880
12881            // If the process is already attached, schedule the creation of the backup agent now.
12882            // If it is not yet live, this will be done when it attaches to the framework.
12883            if (proc.thread != null) {
12884                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
12885                try {
12886                    proc.thread.scheduleCreateBackupAgent(app,
12887                            compatibilityInfoForPackageLocked(app), backupMode);
12888                } catch (RemoteException e) {
12889                    // Will time out on the backup manager side
12890                }
12891            } else {
12892                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
12893            }
12894            // Invariants: at this point, the target app process exists and the application
12895            // is either already running or in the process of coming up.  mBackupTarget and
12896            // mBackupAppName describe the app, so that when it binds back to the AM we
12897            // know that it's scheduled for a backup-agent operation.
12898        }
12899
12900        return true;
12901    }
12902
12903    @Override
12904    public void clearPendingBackup() {
12905        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
12906        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
12907
12908        synchronized (this) {
12909            mBackupTarget = null;
12910            mBackupAppName = null;
12911        }
12912    }
12913
12914    // A backup agent has just come up
12915    public void backupAgentCreated(String agentPackageName, IBinder agent) {
12916        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
12917                + " = " + agent);
12918
12919        synchronized(this) {
12920            if (!agentPackageName.equals(mBackupAppName)) {
12921                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
12922                return;
12923            }
12924        }
12925
12926        long oldIdent = Binder.clearCallingIdentity();
12927        try {
12928            IBackupManager bm = IBackupManager.Stub.asInterface(
12929                    ServiceManager.getService(Context.BACKUP_SERVICE));
12930            bm.agentConnected(agentPackageName, agent);
12931        } catch (RemoteException e) {
12932            // can't happen; the backup manager service is local
12933        } catch (Exception e) {
12934            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12935            e.printStackTrace();
12936        } finally {
12937            Binder.restoreCallingIdentity(oldIdent);
12938        }
12939    }
12940
12941    // done with this agent
12942    public void unbindBackupAgent(ApplicationInfo appInfo) {
12943        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
12944        if (appInfo == null) {
12945            Slog.w(TAG, "unbind backup agent for null app");
12946            return;
12947        }
12948
12949        synchronized(this) {
12950            try {
12951                if (mBackupAppName == null) {
12952                    Slog.w(TAG, "Unbinding backup agent with no active backup");
12953                    return;
12954                }
12955
12956                if (!mBackupAppName.equals(appInfo.packageName)) {
12957                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
12958                    return;
12959                }
12960
12961                // Not backing this app up any more; reset its OOM adjustment
12962                final ProcessRecord proc = mBackupTarget.app;
12963                updateOomAdjLocked(proc);
12964
12965                // If the app crashed during backup, 'thread' will be null here
12966                if (proc.thread != null) {
12967                    try {
12968                        proc.thread.scheduleDestroyBackupAgent(appInfo,
12969                                compatibilityInfoForPackageLocked(appInfo));
12970                    } catch (Exception e) {
12971                        Slog.e(TAG, "Exception when unbinding backup agent:");
12972                        e.printStackTrace();
12973                    }
12974                }
12975            } finally {
12976                mBackupTarget = null;
12977                mBackupAppName = null;
12978            }
12979        }
12980    }
12981    // =========================================================
12982    // BROADCASTS
12983    // =========================================================
12984
12985    private final List getStickiesLocked(String action, IntentFilter filter,
12986            List cur, int userId) {
12987        final ContentResolver resolver = mContext.getContentResolver();
12988        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12989        if (stickies == null) {
12990            return cur;
12991        }
12992        final ArrayList<Intent> list = stickies.get(action);
12993        if (list == null) {
12994            return cur;
12995        }
12996        int N = list.size();
12997        for (int i=0; i<N; i++) {
12998            Intent intent = list.get(i);
12999            if (filter.match(resolver, intent, true, TAG) >= 0) {
13000                if (cur == null) {
13001                    cur = new ArrayList<Intent>();
13002                }
13003                cur.add(intent);
13004            }
13005        }
13006        return cur;
13007    }
13008
13009    boolean isPendingBroadcastProcessLocked(int pid) {
13010        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13011                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13012    }
13013
13014    void skipPendingBroadcastLocked(int pid) {
13015            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13016            for (BroadcastQueue queue : mBroadcastQueues) {
13017                queue.skipPendingBroadcastLocked(pid);
13018            }
13019    }
13020
13021    // The app just attached; send any pending broadcasts that it should receive
13022    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13023        boolean didSomething = false;
13024        for (BroadcastQueue queue : mBroadcastQueues) {
13025            didSomething |= queue.sendPendingBroadcastsLocked(app);
13026        }
13027        return didSomething;
13028    }
13029
13030    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13031            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13032        enforceNotIsolatedCaller("registerReceiver");
13033        int callingUid;
13034        int callingPid;
13035        synchronized(this) {
13036            ProcessRecord callerApp = null;
13037            if (caller != null) {
13038                callerApp = getRecordForAppLocked(caller);
13039                if (callerApp == null) {
13040                    throw new SecurityException(
13041                            "Unable to find app for caller " + caller
13042                            + " (pid=" + Binder.getCallingPid()
13043                            + ") when registering receiver " + receiver);
13044                }
13045                if (callerApp.info.uid != Process.SYSTEM_UID &&
13046                        !callerApp.pkgList.containsKey(callerPackage) &&
13047                        !"android".equals(callerPackage)) {
13048                    throw new SecurityException("Given caller package " + callerPackage
13049                            + " is not running in process " + callerApp);
13050                }
13051                callingUid = callerApp.info.uid;
13052                callingPid = callerApp.pid;
13053            } else {
13054                callerPackage = null;
13055                callingUid = Binder.getCallingUid();
13056                callingPid = Binder.getCallingPid();
13057            }
13058
13059            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13060                    true, true, "registerReceiver", callerPackage);
13061
13062            List allSticky = null;
13063
13064            // Look for any matching sticky broadcasts...
13065            Iterator actions = filter.actionsIterator();
13066            if (actions != null) {
13067                while (actions.hasNext()) {
13068                    String action = (String)actions.next();
13069                    allSticky = getStickiesLocked(action, filter, allSticky,
13070                            UserHandle.USER_ALL);
13071                    allSticky = getStickiesLocked(action, filter, allSticky,
13072                            UserHandle.getUserId(callingUid));
13073                }
13074            } else {
13075                allSticky = getStickiesLocked(null, filter, allSticky,
13076                        UserHandle.USER_ALL);
13077                allSticky = getStickiesLocked(null, filter, allSticky,
13078                        UserHandle.getUserId(callingUid));
13079            }
13080
13081            // The first sticky in the list is returned directly back to
13082            // the client.
13083            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13084
13085            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13086                    + ": " + sticky);
13087
13088            if (receiver == null) {
13089                return sticky;
13090            }
13091
13092            ReceiverList rl
13093                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13094            if (rl == null) {
13095                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13096                        userId, receiver);
13097                if (rl.app != null) {
13098                    rl.app.receivers.add(rl);
13099                } else {
13100                    try {
13101                        receiver.asBinder().linkToDeath(rl, 0);
13102                    } catch (RemoteException e) {
13103                        return sticky;
13104                    }
13105                    rl.linkedToDeath = true;
13106                }
13107                mRegisteredReceivers.put(receiver.asBinder(), rl);
13108            } else if (rl.uid != callingUid) {
13109                throw new IllegalArgumentException(
13110                        "Receiver requested to register for uid " + callingUid
13111                        + " was previously registered for uid " + rl.uid);
13112            } else if (rl.pid != callingPid) {
13113                throw new IllegalArgumentException(
13114                        "Receiver requested to register for pid " + callingPid
13115                        + " was previously registered for pid " + rl.pid);
13116            } else if (rl.userId != userId) {
13117                throw new IllegalArgumentException(
13118                        "Receiver requested to register for user " + userId
13119                        + " was previously registered for user " + rl.userId);
13120            }
13121            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13122                    permission, callingUid, userId);
13123            rl.add(bf);
13124            if (!bf.debugCheck()) {
13125                Slog.w(TAG, "==> For Dynamic broadast");
13126            }
13127            mReceiverResolver.addFilter(bf);
13128
13129            // Enqueue broadcasts for all existing stickies that match
13130            // this filter.
13131            if (allSticky != null) {
13132                ArrayList receivers = new ArrayList();
13133                receivers.add(bf);
13134
13135                int N = allSticky.size();
13136                for (int i=0; i<N; i++) {
13137                    Intent intent = (Intent)allSticky.get(i);
13138                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13139                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13140                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13141                            null, null, false, true, true, -1);
13142                    queue.enqueueParallelBroadcastLocked(r);
13143                    queue.scheduleBroadcastsLocked();
13144                }
13145            }
13146
13147            return sticky;
13148        }
13149    }
13150
13151    public void unregisterReceiver(IIntentReceiver receiver) {
13152        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13153
13154        final long origId = Binder.clearCallingIdentity();
13155        try {
13156            boolean doTrim = false;
13157
13158            synchronized(this) {
13159                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13160                if (rl != null) {
13161                    if (rl.curBroadcast != null) {
13162                        BroadcastRecord r = rl.curBroadcast;
13163                        final boolean doNext = finishReceiverLocked(
13164                                receiver.asBinder(), r.resultCode, r.resultData,
13165                                r.resultExtras, r.resultAbort);
13166                        if (doNext) {
13167                            doTrim = true;
13168                            r.queue.processNextBroadcast(false);
13169                        }
13170                    }
13171
13172                    if (rl.app != null) {
13173                        rl.app.receivers.remove(rl);
13174                    }
13175                    removeReceiverLocked(rl);
13176                    if (rl.linkedToDeath) {
13177                        rl.linkedToDeath = false;
13178                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13179                    }
13180                }
13181            }
13182
13183            // If we actually concluded any broadcasts, we might now be able
13184            // to trim the recipients' apps from our working set
13185            if (doTrim) {
13186                trimApplications();
13187                return;
13188            }
13189
13190        } finally {
13191            Binder.restoreCallingIdentity(origId);
13192        }
13193    }
13194
13195    void removeReceiverLocked(ReceiverList rl) {
13196        mRegisteredReceivers.remove(rl.receiver.asBinder());
13197        int N = rl.size();
13198        for (int i=0; i<N; i++) {
13199            mReceiverResolver.removeFilter(rl.get(i));
13200        }
13201    }
13202
13203    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13204        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13205            ProcessRecord r = mLruProcesses.get(i);
13206            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13207                try {
13208                    r.thread.dispatchPackageBroadcast(cmd, packages);
13209                } catch (RemoteException ex) {
13210                }
13211            }
13212        }
13213    }
13214
13215    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13216            int[] users) {
13217        List<ResolveInfo> receivers = null;
13218        try {
13219            HashSet<ComponentName> singleUserReceivers = null;
13220            boolean scannedFirstReceivers = false;
13221            for (int user : users) {
13222                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13223                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13224                if (user != 0 && newReceivers != null) {
13225                    // If this is not the primary user, we need to check for
13226                    // any receivers that should be filtered out.
13227                    for (int i=0; i<newReceivers.size(); i++) {
13228                        ResolveInfo ri = newReceivers.get(i);
13229                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13230                            newReceivers.remove(i);
13231                            i--;
13232                        }
13233                    }
13234                }
13235                if (newReceivers != null && newReceivers.size() == 0) {
13236                    newReceivers = null;
13237                }
13238                if (receivers == null) {
13239                    receivers = newReceivers;
13240                } else if (newReceivers != null) {
13241                    // We need to concatenate the additional receivers
13242                    // found with what we have do far.  This would be easy,
13243                    // but we also need to de-dup any receivers that are
13244                    // singleUser.
13245                    if (!scannedFirstReceivers) {
13246                        // Collect any single user receivers we had already retrieved.
13247                        scannedFirstReceivers = true;
13248                        for (int i=0; i<receivers.size(); i++) {
13249                            ResolveInfo ri = receivers.get(i);
13250                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13251                                ComponentName cn = new ComponentName(
13252                                        ri.activityInfo.packageName, ri.activityInfo.name);
13253                                if (singleUserReceivers == null) {
13254                                    singleUserReceivers = new HashSet<ComponentName>();
13255                                }
13256                                singleUserReceivers.add(cn);
13257                            }
13258                        }
13259                    }
13260                    // Add the new results to the existing results, tracking
13261                    // and de-dupping single user receivers.
13262                    for (int i=0; i<newReceivers.size(); i++) {
13263                        ResolveInfo ri = newReceivers.get(i);
13264                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13265                            ComponentName cn = new ComponentName(
13266                                    ri.activityInfo.packageName, ri.activityInfo.name);
13267                            if (singleUserReceivers == null) {
13268                                singleUserReceivers = new HashSet<ComponentName>();
13269                            }
13270                            if (!singleUserReceivers.contains(cn)) {
13271                                singleUserReceivers.add(cn);
13272                                receivers.add(ri);
13273                            }
13274                        } else {
13275                            receivers.add(ri);
13276                        }
13277                    }
13278                }
13279            }
13280        } catch (RemoteException ex) {
13281            // pm is in same process, this will never happen.
13282        }
13283        return receivers;
13284    }
13285
13286    private final int broadcastIntentLocked(ProcessRecord callerApp,
13287            String callerPackage, Intent intent, String resolvedType,
13288            IIntentReceiver resultTo, int resultCode, String resultData,
13289            Bundle map, String requiredPermission, int appOp,
13290            boolean ordered, boolean sticky, int callingPid, int callingUid,
13291            int userId) {
13292        intent = new Intent(intent);
13293
13294        // By default broadcasts do not go to stopped apps.
13295        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13296
13297        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13298            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13299            + " ordered=" + ordered + " userid=" + userId);
13300        if ((resultTo != null) && !ordered) {
13301            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13302        }
13303
13304        userId = handleIncomingUser(callingPid, callingUid, userId,
13305                true, false, "broadcast", callerPackage);
13306
13307        // Make sure that the user who is receiving this broadcast is started.
13308        // If not, we will just skip it.
13309        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13310            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13311                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13312                Slog.w(TAG, "Skipping broadcast of " + intent
13313                        + ": user " + userId + " is stopped");
13314                return ActivityManager.BROADCAST_SUCCESS;
13315            }
13316        }
13317
13318        /*
13319         * Prevent non-system code (defined here to be non-persistent
13320         * processes) from sending protected broadcasts.
13321         */
13322        int callingAppId = UserHandle.getAppId(callingUid);
13323        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13324            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
13325            callingUid == 0) {
13326            // Always okay.
13327        } else if (callerApp == null || !callerApp.persistent) {
13328            try {
13329                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13330                        intent.getAction())) {
13331                    String msg = "Permission Denial: not allowed to send broadcast "
13332                            + intent.getAction() + " from pid="
13333                            + callingPid + ", uid=" + callingUid;
13334                    Slog.w(TAG, msg);
13335                    throw new SecurityException(msg);
13336                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13337                    // Special case for compatibility: we don't want apps to send this,
13338                    // but historically it has not been protected and apps may be using it
13339                    // to poke their own app widget.  So, instead of making it protected,
13340                    // just limit it to the caller.
13341                    if (callerApp == null) {
13342                        String msg = "Permission Denial: not allowed to send broadcast "
13343                                + intent.getAction() + " from unknown caller.";
13344                        Slog.w(TAG, msg);
13345                        throw new SecurityException(msg);
13346                    } else if (intent.getComponent() != null) {
13347                        // They are good enough to send to an explicit component...  verify
13348                        // it is being sent to the calling app.
13349                        if (!intent.getComponent().getPackageName().equals(
13350                                callerApp.info.packageName)) {
13351                            String msg = "Permission Denial: not allowed to send broadcast "
13352                                    + intent.getAction() + " to "
13353                                    + intent.getComponent().getPackageName() + " from "
13354                                    + callerApp.info.packageName;
13355                            Slog.w(TAG, msg);
13356                            throw new SecurityException(msg);
13357                        }
13358                    } else {
13359                        // Limit broadcast to their own package.
13360                        intent.setPackage(callerApp.info.packageName);
13361                    }
13362                }
13363            } catch (RemoteException e) {
13364                Slog.w(TAG, "Remote exception", e);
13365                return ActivityManager.BROADCAST_SUCCESS;
13366            }
13367        }
13368
13369        // Handle special intents: if this broadcast is from the package
13370        // manager about a package being removed, we need to remove all of
13371        // its activities from the history stack.
13372        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
13373                intent.getAction());
13374        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
13375                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
13376                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
13377                || uidRemoved) {
13378            if (checkComponentPermission(
13379                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
13380                    callingPid, callingUid, -1, true)
13381                    == PackageManager.PERMISSION_GRANTED) {
13382                if (uidRemoved) {
13383                    final Bundle intentExtras = intent.getExtras();
13384                    final int uid = intentExtras != null
13385                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
13386                    if (uid >= 0) {
13387                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
13388                        synchronized (bs) {
13389                            bs.removeUidStatsLocked(uid);
13390                        }
13391                        mAppOpsService.uidRemoved(uid);
13392                    }
13393                } else {
13394                    // If resources are unavailable just force stop all
13395                    // those packages and flush the attribute cache as well.
13396                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
13397                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13398                        if (list != null && (list.length > 0)) {
13399                            for (String pkg : list) {
13400                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
13401                                        "storage unmount");
13402                            }
13403                            sendPackageBroadcastLocked(
13404                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
13405                        }
13406                    } else {
13407                        Uri data = intent.getData();
13408                        String ssp;
13409                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13410                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
13411                                    intent.getAction());
13412                            boolean fullUninstall = removed &&
13413                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
13414                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
13415                                forceStopPackageLocked(ssp, UserHandle.getAppId(
13416                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
13417                                        false, fullUninstall, userId,
13418                                        removed ? "pkg removed" : "pkg changed");
13419                            }
13420                            if (removed) {
13421                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
13422                                        new String[] {ssp}, userId);
13423                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
13424                                    mAppOpsService.packageRemoved(
13425                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
13426
13427                                    // Remove all permissions granted from/to this package
13428                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
13429                                }
13430                            }
13431                        }
13432                    }
13433                }
13434            } else {
13435                String msg = "Permission Denial: " + intent.getAction()
13436                        + " broadcast from " + callerPackage + " (pid=" + callingPid
13437                        + ", uid=" + callingUid + ")"
13438                        + " requires "
13439                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
13440                Slog.w(TAG, msg);
13441                throw new SecurityException(msg);
13442            }
13443
13444        // Special case for adding a package: by default turn on compatibility
13445        // mode.
13446        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
13447            Uri data = intent.getData();
13448            String ssp;
13449            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
13450                mCompatModePackages.handlePackageAddedLocked(ssp,
13451                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
13452            }
13453        }
13454
13455        /*
13456         * If this is the time zone changed action, queue up a message that will reset the timezone
13457         * of all currently running processes. This message will get queued up before the broadcast
13458         * happens.
13459         */
13460        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
13461            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
13462        }
13463
13464        /*
13465         * If the user set the time, let all running processes know.
13466         */
13467        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
13468            final int is24Hour = intent.getBooleanExtra(
13469                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
13470            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
13471        }
13472
13473        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
13474            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
13475        }
13476
13477        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
13478            ProxyProperties proxy = intent.getParcelableExtra("proxy");
13479            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
13480        }
13481
13482        // Add to the sticky list if requested.
13483        if (sticky) {
13484            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
13485                    callingPid, callingUid)
13486                    != PackageManager.PERMISSION_GRANTED) {
13487                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
13488                        + callingPid + ", uid=" + callingUid
13489                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13490                Slog.w(TAG, msg);
13491                throw new SecurityException(msg);
13492            }
13493            if (requiredPermission != null) {
13494                Slog.w(TAG, "Can't broadcast sticky intent " + intent
13495                        + " and enforce permission " + requiredPermission);
13496                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
13497            }
13498            if (intent.getComponent() != null) {
13499                throw new SecurityException(
13500                        "Sticky broadcasts can't target a specific component");
13501            }
13502            // We use userId directly here, since the "all" target is maintained
13503            // as a separate set of sticky broadcasts.
13504            if (userId != UserHandle.USER_ALL) {
13505                // But first, if this is not a broadcast to all users, then
13506                // make sure it doesn't conflict with an existing broadcast to
13507                // all users.
13508                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
13509                        UserHandle.USER_ALL);
13510                if (stickies != null) {
13511                    ArrayList<Intent> list = stickies.get(intent.getAction());
13512                    if (list != null) {
13513                        int N = list.size();
13514                        int i;
13515                        for (i=0; i<N; i++) {
13516                            if (intent.filterEquals(list.get(i))) {
13517                                throw new IllegalArgumentException(
13518                                        "Sticky broadcast " + intent + " for user "
13519                                        + userId + " conflicts with existing global broadcast");
13520                            }
13521                        }
13522                    }
13523                }
13524            }
13525            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13526            if (stickies == null) {
13527                stickies = new ArrayMap<String, ArrayList<Intent>>();
13528                mStickyBroadcasts.put(userId, stickies);
13529            }
13530            ArrayList<Intent> list = stickies.get(intent.getAction());
13531            if (list == null) {
13532                list = new ArrayList<Intent>();
13533                stickies.put(intent.getAction(), list);
13534            }
13535            int N = list.size();
13536            int i;
13537            for (i=0; i<N; i++) {
13538                if (intent.filterEquals(list.get(i))) {
13539                    // This sticky already exists, replace it.
13540                    list.set(i, new Intent(intent));
13541                    break;
13542                }
13543            }
13544            if (i >= N) {
13545                list.add(new Intent(intent));
13546            }
13547        }
13548
13549        int[] users;
13550        if (userId == UserHandle.USER_ALL) {
13551            // Caller wants broadcast to go to all started users.
13552            users = mStartedUserArray;
13553        } else {
13554            // Caller wants broadcast to go to one specific user.
13555            users = new int[] {userId};
13556        }
13557
13558        // Figure out who all will receive this broadcast.
13559        List receivers = null;
13560        List<BroadcastFilter> registeredReceivers = null;
13561        // Need to resolve the intent to interested receivers...
13562        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13563                 == 0) {
13564            receivers = collectReceiverComponents(intent, resolvedType, users);
13565        }
13566        if (intent.getComponent() == null) {
13567            registeredReceivers = mReceiverResolver.queryIntent(intent,
13568                    resolvedType, false, userId);
13569        }
13570
13571        final boolean replacePending =
13572                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13573
13574        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
13575                + " replacePending=" + replacePending);
13576
13577        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13578        if (!ordered && NR > 0) {
13579            // If we are not serializing this broadcast, then send the
13580            // registered receivers separately so they don't wait for the
13581            // components to be launched.
13582            final BroadcastQueue queue = broadcastQueueForIntent(intent);
13583            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13584                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
13585                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
13586                    ordered, sticky, false, userId);
13587            if (DEBUG_BROADCAST) Slog.v(
13588                    TAG, "Enqueueing parallel broadcast " + r);
13589            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
13590            if (!replaced) {
13591                queue.enqueueParallelBroadcastLocked(r);
13592                queue.scheduleBroadcastsLocked();
13593            }
13594            registeredReceivers = null;
13595            NR = 0;
13596        }
13597
13598        // Merge into one list.
13599        int ir = 0;
13600        if (receivers != null) {
13601            // A special case for PACKAGE_ADDED: do not allow the package
13602            // being added to see this broadcast.  This prevents them from
13603            // using this as a back door to get run as soon as they are
13604            // installed.  Maybe in the future we want to have a special install
13605            // broadcast or such for apps, but we'd like to deliberately make
13606            // this decision.
13607            String skipPackages[] = null;
13608            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13609                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13610                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
13611                Uri data = intent.getData();
13612                if (data != null) {
13613                    String pkgName = data.getSchemeSpecificPart();
13614                    if (pkgName != null) {
13615                        skipPackages = new String[] { pkgName };
13616                    }
13617                }
13618            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
13619                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
13620            }
13621            if (skipPackages != null && (skipPackages.length > 0)) {
13622                for (String skipPackage : skipPackages) {
13623                    if (skipPackage != null) {
13624                        int NT = receivers.size();
13625                        for (int it=0; it<NT; it++) {
13626                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
13627                            if (curt.activityInfo.packageName.equals(skipPackage)) {
13628                                receivers.remove(it);
13629                                it--;
13630                                NT--;
13631                            }
13632                        }
13633                    }
13634                }
13635            }
13636
13637            int NT = receivers != null ? receivers.size() : 0;
13638            int it = 0;
13639            ResolveInfo curt = null;
13640            BroadcastFilter curr = null;
13641            while (it < NT && ir < NR) {
13642                if (curt == null) {
13643                    curt = (ResolveInfo)receivers.get(it);
13644                }
13645                if (curr == null) {
13646                    curr = registeredReceivers.get(ir);
13647                }
13648                if (curr.getPriority() >= curt.priority) {
13649                    // Insert this broadcast record into the final list.
13650                    receivers.add(it, curr);
13651                    ir++;
13652                    curr = null;
13653                    it++;
13654                    NT++;
13655                } else {
13656                    // Skip to the next ResolveInfo in the final list.
13657                    it++;
13658                    curt = null;
13659                }
13660            }
13661        }
13662        while (ir < NR) {
13663            if (receivers == null) {
13664                receivers = new ArrayList();
13665            }
13666            receivers.add(registeredReceivers.get(ir));
13667            ir++;
13668        }
13669
13670        if ((receivers != null && receivers.size() > 0)
13671                || resultTo != null) {
13672            BroadcastQueue queue = broadcastQueueForIntent(intent);
13673            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
13674                    callerPackage, callingPid, callingUid, resolvedType,
13675                    requiredPermission, appOp, receivers, resultTo, resultCode,
13676                    resultData, map, ordered, sticky, false, userId);
13677            if (DEBUG_BROADCAST) Slog.v(
13678                    TAG, "Enqueueing ordered broadcast " + r
13679                    + ": prev had " + queue.mOrderedBroadcasts.size());
13680            if (DEBUG_BROADCAST) {
13681                int seq = r.intent.getIntExtra("seq", -1);
13682                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
13683            }
13684            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
13685            if (!replaced) {
13686                queue.enqueueOrderedBroadcastLocked(r);
13687                queue.scheduleBroadcastsLocked();
13688            }
13689        }
13690
13691        return ActivityManager.BROADCAST_SUCCESS;
13692    }
13693
13694    final Intent verifyBroadcastLocked(Intent intent) {
13695        // Refuse possible leaked file descriptors
13696        if (intent != null && intent.hasFileDescriptors() == true) {
13697            throw new IllegalArgumentException("File descriptors passed in Intent");
13698        }
13699
13700        int flags = intent.getFlags();
13701
13702        if (!mProcessesReady) {
13703            // if the caller really truly claims to know what they're doing, go
13704            // ahead and allow the broadcast without launching any receivers
13705            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13706                intent = new Intent(intent);
13707                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13708            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13709                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13710                        + " before boot completion");
13711                throw new IllegalStateException("Cannot broadcast before boot completed");
13712            }
13713        }
13714
13715        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13716            throw new IllegalArgumentException(
13717                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13718        }
13719
13720        return intent;
13721    }
13722
13723    public final int broadcastIntent(IApplicationThread caller,
13724            Intent intent, String resolvedType, IIntentReceiver resultTo,
13725            int resultCode, String resultData, Bundle map,
13726            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
13727        enforceNotIsolatedCaller("broadcastIntent");
13728        synchronized(this) {
13729            intent = verifyBroadcastLocked(intent);
13730
13731            final ProcessRecord callerApp = getRecordForAppLocked(caller);
13732            final int callingPid = Binder.getCallingPid();
13733            final int callingUid = Binder.getCallingUid();
13734            final long origId = Binder.clearCallingIdentity();
13735            int res = broadcastIntentLocked(callerApp,
13736                    callerApp != null ? callerApp.info.packageName : null,
13737                    intent, resolvedType, resultTo,
13738                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
13739                    callingPid, callingUid, userId);
13740            Binder.restoreCallingIdentity(origId);
13741            return res;
13742        }
13743    }
13744
13745    int broadcastIntentInPackage(String packageName, int uid,
13746            Intent intent, String resolvedType, IIntentReceiver resultTo,
13747            int resultCode, String resultData, Bundle map,
13748            String requiredPermission, boolean serialized, boolean sticky, int userId) {
13749        synchronized(this) {
13750            intent = verifyBroadcastLocked(intent);
13751
13752            final long origId = Binder.clearCallingIdentity();
13753            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13754                    resultTo, resultCode, resultData, map, requiredPermission,
13755                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
13756            Binder.restoreCallingIdentity(origId);
13757            return res;
13758        }
13759    }
13760
13761    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
13762        // Refuse possible leaked file descriptors
13763        if (intent != null && intent.hasFileDescriptors() == true) {
13764            throw new IllegalArgumentException("File descriptors passed in Intent");
13765        }
13766
13767        userId = handleIncomingUser(Binder.getCallingPid(),
13768                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
13769
13770        synchronized(this) {
13771            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13772                    != PackageManager.PERMISSION_GRANTED) {
13773                String msg = "Permission Denial: unbroadcastIntent() from pid="
13774                        + Binder.getCallingPid()
13775                        + ", uid=" + Binder.getCallingUid()
13776                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
13777                Slog.w(TAG, msg);
13778                throw new SecurityException(msg);
13779            }
13780            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13781            if (stickies != null) {
13782                ArrayList<Intent> list = stickies.get(intent.getAction());
13783                if (list != null) {
13784                    int N = list.size();
13785                    int i;
13786                    for (i=0; i<N; i++) {
13787                        if (intent.filterEquals(list.get(i))) {
13788                            list.remove(i);
13789                            break;
13790                        }
13791                    }
13792                    if (list.size() <= 0) {
13793                        stickies.remove(intent.getAction());
13794                    }
13795                }
13796                if (stickies.size() <= 0) {
13797                    mStickyBroadcasts.remove(userId);
13798                }
13799            }
13800        }
13801    }
13802
13803    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13804            String resultData, Bundle resultExtras, boolean resultAbort) {
13805        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13806        if (r == null) {
13807            Slog.w(TAG, "finishReceiver called but not found on queue");
13808            return false;
13809        }
13810
13811        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
13812    }
13813
13814    void backgroundServicesFinishedLocked(int userId) {
13815        for (BroadcastQueue queue : mBroadcastQueues) {
13816            queue.backgroundServicesFinishedLocked(userId);
13817        }
13818    }
13819
13820    public void finishReceiver(IBinder who, int resultCode, String resultData,
13821            Bundle resultExtras, boolean resultAbort) {
13822        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
13823
13824        // Refuse possible leaked file descriptors
13825        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13826            throw new IllegalArgumentException("File descriptors passed in Bundle");
13827        }
13828
13829        final long origId = Binder.clearCallingIdentity();
13830        try {
13831            boolean doNext = false;
13832            BroadcastRecord r;
13833
13834            synchronized(this) {
13835                r = broadcastRecordForReceiverLocked(who);
13836                if (r != null) {
13837                    doNext = r.queue.finishReceiverLocked(r, resultCode,
13838                        resultData, resultExtras, resultAbort, true);
13839                }
13840            }
13841
13842            if (doNext) {
13843                r.queue.processNextBroadcast(false);
13844            }
13845            trimApplications();
13846        } finally {
13847            Binder.restoreCallingIdentity(origId);
13848        }
13849    }
13850
13851    // =========================================================
13852    // INSTRUMENTATION
13853    // =========================================================
13854
13855    public boolean startInstrumentation(ComponentName className,
13856            String profileFile, int flags, Bundle arguments,
13857            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
13858            int userId) {
13859        enforceNotIsolatedCaller("startInstrumentation");
13860        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
13861                userId, false, true, "startInstrumentation", null);
13862        // Refuse possible leaked file descriptors
13863        if (arguments != null && arguments.hasFileDescriptors()) {
13864            throw new IllegalArgumentException("File descriptors passed in Bundle");
13865        }
13866
13867        synchronized(this) {
13868            InstrumentationInfo ii = null;
13869            ApplicationInfo ai = null;
13870            try {
13871                ii = mContext.getPackageManager().getInstrumentationInfo(
13872                    className, STOCK_PM_FLAGS);
13873                ai = AppGlobals.getPackageManager().getApplicationInfo(
13874                        ii.targetPackage, STOCK_PM_FLAGS, userId);
13875            } catch (PackageManager.NameNotFoundException e) {
13876            } catch (RemoteException e) {
13877            }
13878            if (ii == null) {
13879                reportStartInstrumentationFailure(watcher, className,
13880                        "Unable to find instrumentation info for: " + className);
13881                return false;
13882            }
13883            if (ai == null) {
13884                reportStartInstrumentationFailure(watcher, className,
13885                        "Unable to find instrumentation target package: " + ii.targetPackage);
13886                return false;
13887            }
13888
13889            int match = mContext.getPackageManager().checkSignatures(
13890                    ii.targetPackage, ii.packageName);
13891            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13892                String msg = "Permission Denial: starting instrumentation "
13893                        + className + " from pid="
13894                        + Binder.getCallingPid()
13895                        + ", uid=" + Binder.getCallingPid()
13896                        + " not allowed because package " + ii.packageName
13897                        + " does not have a signature matching the target "
13898                        + ii.targetPackage;
13899                reportStartInstrumentationFailure(watcher, className, msg);
13900                throw new SecurityException(msg);
13901            }
13902
13903            final long origId = Binder.clearCallingIdentity();
13904            // Instrumentation can kill and relaunch even persistent processes
13905            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
13906                    "start instr");
13907            ProcessRecord app = addAppLocked(ai, false);
13908            app.instrumentationClass = className;
13909            app.instrumentationInfo = ai;
13910            app.instrumentationProfileFile = profileFile;
13911            app.instrumentationArguments = arguments;
13912            app.instrumentationWatcher = watcher;
13913            app.instrumentationUiAutomationConnection = uiAutomationConnection;
13914            app.instrumentationResultClass = className;
13915            Binder.restoreCallingIdentity(origId);
13916        }
13917
13918        return true;
13919    }
13920
13921    /**
13922     * Report errors that occur while attempting to start Instrumentation.  Always writes the
13923     * error to the logs, but if somebody is watching, send the report there too.  This enables
13924     * the "am" command to report errors with more information.
13925     *
13926     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
13927     * @param cn The component name of the instrumentation.
13928     * @param report The error report.
13929     */
13930    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13931            ComponentName cn, String report) {
13932        Slog.w(TAG, report);
13933        try {
13934            if (watcher != null) {
13935                Bundle results = new Bundle();
13936                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13937                results.putString("Error", report);
13938                watcher.instrumentationStatus(cn, -1, results);
13939            }
13940        } catch (RemoteException e) {
13941            Slog.w(TAG, e);
13942        }
13943    }
13944
13945    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13946        if (app.instrumentationWatcher != null) {
13947            try {
13948                // NOTE:  IInstrumentationWatcher *must* be oneway here
13949                app.instrumentationWatcher.instrumentationFinished(
13950                    app.instrumentationClass,
13951                    resultCode,
13952                    results);
13953            } catch (RemoteException e) {
13954            }
13955        }
13956        if (app.instrumentationUiAutomationConnection != null) {
13957            try {
13958                app.instrumentationUiAutomationConnection.shutdown();
13959            } catch (RemoteException re) {
13960                /* ignore */
13961            }
13962            // Only a UiAutomation can set this flag and now that
13963            // it is finished we make sure it is reset to its default.
13964            mUserIsMonkey = false;
13965        }
13966        app.instrumentationWatcher = null;
13967        app.instrumentationUiAutomationConnection = null;
13968        app.instrumentationClass = null;
13969        app.instrumentationInfo = null;
13970        app.instrumentationProfileFile = null;
13971        app.instrumentationArguments = null;
13972
13973        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
13974                "finished inst");
13975    }
13976
13977    public void finishInstrumentation(IApplicationThread target,
13978            int resultCode, Bundle results) {
13979        int userId = UserHandle.getCallingUserId();
13980        // Refuse possible leaked file descriptors
13981        if (results != null && results.hasFileDescriptors()) {
13982            throw new IllegalArgumentException("File descriptors passed in Intent");
13983        }
13984
13985        synchronized(this) {
13986            ProcessRecord app = getRecordForAppLocked(target);
13987            if (app == null) {
13988                Slog.w(TAG, "finishInstrumentation: no app for " + target);
13989                return;
13990            }
13991            final long origId = Binder.clearCallingIdentity();
13992            finishInstrumentationLocked(app, resultCode, results);
13993            Binder.restoreCallingIdentity(origId);
13994        }
13995    }
13996
13997    // =========================================================
13998    // CONFIGURATION
13999    // =========================================================
14000
14001    public ConfigurationInfo getDeviceConfigurationInfo() {
14002        ConfigurationInfo config = new ConfigurationInfo();
14003        synchronized (this) {
14004            config.reqTouchScreen = mConfiguration.touchscreen;
14005            config.reqKeyboardType = mConfiguration.keyboard;
14006            config.reqNavigation = mConfiguration.navigation;
14007            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14008                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14009                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14010            }
14011            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14012                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14013                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14014            }
14015            config.reqGlEsVersion = GL_ES_VERSION;
14016        }
14017        return config;
14018    }
14019
14020    ActivityStack getFocusedStack() {
14021        return mStackSupervisor.getFocusedStack();
14022    }
14023
14024    public Configuration getConfiguration() {
14025        Configuration ci;
14026        synchronized(this) {
14027            ci = new Configuration(mConfiguration);
14028        }
14029        return ci;
14030    }
14031
14032    public void updatePersistentConfiguration(Configuration values) {
14033        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14034                "updateConfiguration()");
14035        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14036                "updateConfiguration()");
14037        if (values == null) {
14038            throw new NullPointerException("Configuration must not be null");
14039        }
14040
14041        synchronized(this) {
14042            final long origId = Binder.clearCallingIdentity();
14043            updateConfigurationLocked(values, null, true, false);
14044            Binder.restoreCallingIdentity(origId);
14045        }
14046    }
14047
14048    public void updateConfiguration(Configuration values) {
14049        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14050                "updateConfiguration()");
14051
14052        synchronized(this) {
14053            if (values == null && mWindowManager != null) {
14054                // sentinel: fetch the current configuration from the window manager
14055                values = mWindowManager.computeNewConfiguration();
14056            }
14057
14058            if (mWindowManager != null) {
14059                mProcessList.applyDisplaySize(mWindowManager);
14060            }
14061
14062            final long origId = Binder.clearCallingIdentity();
14063            if (values != null) {
14064                Settings.System.clearConfiguration(values);
14065            }
14066            updateConfigurationLocked(values, null, false, false);
14067            Binder.restoreCallingIdentity(origId);
14068        }
14069    }
14070
14071    /**
14072     * Do either or both things: (1) change the current configuration, and (2)
14073     * make sure the given activity is running with the (now) current
14074     * configuration.  Returns true if the activity has been left running, or
14075     * false if <var>starting</var> is being destroyed to match the new
14076     * configuration.
14077     * @param persistent TODO
14078     */
14079    boolean updateConfigurationLocked(Configuration values,
14080            ActivityRecord starting, boolean persistent, boolean initLocale) {
14081        int changes = 0;
14082
14083        if (values != null) {
14084            Configuration newConfig = new Configuration(mConfiguration);
14085            changes = newConfig.updateFrom(values);
14086            if (changes != 0) {
14087                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14088                    Slog.i(TAG, "Updating configuration to: " + values);
14089                }
14090
14091                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14092
14093                if (values.locale != null && !initLocale) {
14094                    saveLocaleLocked(values.locale,
14095                                     !values.locale.equals(mConfiguration.locale),
14096                                     values.userSetLocale);
14097                }
14098
14099                mConfigurationSeq++;
14100                if (mConfigurationSeq <= 0) {
14101                    mConfigurationSeq = 1;
14102                }
14103                newConfig.seq = mConfigurationSeq;
14104                mConfiguration = newConfig;
14105                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14106
14107                final Configuration configCopy = new Configuration(mConfiguration);
14108
14109                // TODO: If our config changes, should we auto dismiss any currently
14110                // showing dialogs?
14111                mShowDialogs = shouldShowDialogs(newConfig);
14112
14113                AttributeCache ac = AttributeCache.instance();
14114                if (ac != null) {
14115                    ac.updateConfiguration(configCopy);
14116                }
14117
14118                // Make sure all resources in our process are updated
14119                // right now, so that anyone who is going to retrieve
14120                // resource values after we return will be sure to get
14121                // the new ones.  This is especially important during
14122                // boot, where the first config change needs to guarantee
14123                // all resources have that config before following boot
14124                // code is executed.
14125                mSystemThread.applyConfigurationToResources(configCopy);
14126
14127                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14128                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14129                    msg.obj = new Configuration(configCopy);
14130                    mHandler.sendMessage(msg);
14131                }
14132
14133                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14134                    ProcessRecord app = mLruProcesses.get(i);
14135                    try {
14136                        if (app.thread != null) {
14137                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14138                                    + app.processName + " new config " + mConfiguration);
14139                            app.thread.scheduleConfigurationChanged(configCopy);
14140                        }
14141                    } catch (Exception e) {
14142                    }
14143                }
14144                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14145                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14146                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14147                        | Intent.FLAG_RECEIVER_FOREGROUND);
14148                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14149                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14150                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14151                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14152                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14153                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14154                    broadcastIntentLocked(null, null, intent,
14155                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14156                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14157                }
14158            }
14159        }
14160
14161        boolean kept = true;
14162        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14163        // mainStack is null during startup.
14164        if (mainStack != null) {
14165            if (changes != 0 && starting == null) {
14166                // If the configuration changed, and the caller is not already
14167                // in the process of starting an activity, then find the top
14168                // activity to check if its configuration needs to change.
14169                starting = mainStack.topRunningActivityLocked(null);
14170            }
14171
14172            if (starting != null) {
14173                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14174                // And we need to make sure at this point that all other activities
14175                // are made visible with the correct configuration.
14176                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14177            }
14178        }
14179
14180        if (values != null && mWindowManager != null) {
14181            mWindowManager.setNewConfiguration(mConfiguration);
14182        }
14183
14184        return kept;
14185    }
14186
14187    /**
14188     * Decide based on the configuration whether we should shouw the ANR,
14189     * crash, etc dialogs.  The idea is that if there is no affordnace to
14190     * press the on-screen buttons, we shouldn't show the dialog.
14191     *
14192     * A thought: SystemUI might also want to get told about this, the Power
14193     * dialog / global actions also might want different behaviors.
14194     */
14195    private static final boolean shouldShowDialogs(Configuration config) {
14196        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14197                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14198    }
14199
14200    /**
14201     * Save the locale.  You must be inside a synchronized (this) block.
14202     */
14203    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14204        if(isDiff) {
14205            SystemProperties.set("user.language", l.getLanguage());
14206            SystemProperties.set("user.region", l.getCountry());
14207        }
14208
14209        if(isPersist) {
14210            SystemProperties.set("persist.sys.language", l.getLanguage());
14211            SystemProperties.set("persist.sys.country", l.getCountry());
14212            SystemProperties.set("persist.sys.localevar", l.getVariant());
14213        }
14214    }
14215
14216    @Override
14217    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14218        ActivityRecord srec = ActivityRecord.forToken(token);
14219        return srec != null && srec.task.affinity != null &&
14220                srec.task.affinity.equals(destAffinity);
14221    }
14222
14223    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14224            Intent resultData) {
14225
14226        synchronized (this) {
14227            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14228            if (stack != null) {
14229                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14230            }
14231            return false;
14232        }
14233    }
14234
14235    public int getLaunchedFromUid(IBinder activityToken) {
14236        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14237        if (srec == null) {
14238            return -1;
14239        }
14240        return srec.launchedFromUid;
14241    }
14242
14243    public String getLaunchedFromPackage(IBinder activityToken) {
14244        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14245        if (srec == null) {
14246            return null;
14247        }
14248        return srec.launchedFromPackage;
14249    }
14250
14251    // =========================================================
14252    // LIFETIME MANAGEMENT
14253    // =========================================================
14254
14255    // Returns which broadcast queue the app is the current [or imminent] receiver
14256    // on, or 'null' if the app is not an active broadcast recipient.
14257    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14258        BroadcastRecord r = app.curReceiver;
14259        if (r != null) {
14260            return r.queue;
14261        }
14262
14263        // It's not the current receiver, but it might be starting up to become one
14264        synchronized (this) {
14265            for (BroadcastQueue queue : mBroadcastQueues) {
14266                r = queue.mPendingBroadcast;
14267                if (r != null && r.curApp == app) {
14268                    // found it; report which queue it's in
14269                    return queue;
14270                }
14271            }
14272        }
14273
14274        return null;
14275    }
14276
14277    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14278            boolean doingAll, long now) {
14279        if (mAdjSeq == app.adjSeq) {
14280            // This adjustment has already been computed.
14281            return app.curRawAdj;
14282        }
14283
14284        if (app.thread == null) {
14285            app.adjSeq = mAdjSeq;
14286            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14287            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14288            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14289        }
14290
14291        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14292        app.adjSource = null;
14293        app.adjTarget = null;
14294        app.empty = false;
14295        app.cached = false;
14296
14297        final int activitiesSize = app.activities.size();
14298
14299        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14300            // The max adjustment doesn't allow this app to be anything
14301            // below foreground, so it is not worth doing work for it.
14302            app.adjType = "fixed";
14303            app.adjSeq = mAdjSeq;
14304            app.curRawAdj = app.maxAdj;
14305            app.foregroundActivities = false;
14306            app.keeping = true;
14307            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14308            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14309            // System process can do UI, and when they do we want to have
14310            // them trim their memory after the user leaves the UI.  To
14311            // facilitate this, here we need to determine whether or not it
14312            // is currently showing UI.
14313            app.systemNoUi = true;
14314            if (app == TOP_APP) {
14315                app.systemNoUi = false;
14316            } else if (activitiesSize > 0) {
14317                for (int j = 0; j < activitiesSize; j++) {
14318                    final ActivityRecord r = app.activities.get(j);
14319                    if (r.visible) {
14320                        app.systemNoUi = false;
14321                    }
14322                }
14323            }
14324            if (!app.systemNoUi) {
14325                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14326            }
14327            return (app.curAdj=app.maxAdj);
14328        }
14329
14330        app.keeping = false;
14331        app.systemNoUi = false;
14332
14333        // Determine the importance of the process, starting with most
14334        // important to least, and assign an appropriate OOM adjustment.
14335        int adj;
14336        int schedGroup;
14337        int procState;
14338        boolean foregroundActivities = false;
14339        boolean interesting = false;
14340        BroadcastQueue queue;
14341        if (app == TOP_APP) {
14342            // The last app on the list is the foreground app.
14343            adj = ProcessList.FOREGROUND_APP_ADJ;
14344            schedGroup = Process.THREAD_GROUP_DEFAULT;
14345            app.adjType = "top-activity";
14346            foregroundActivities = true;
14347            interesting = true;
14348            procState = ActivityManager.PROCESS_STATE_TOP;
14349        } else if (app.instrumentationClass != null) {
14350            // Don't want to kill running instrumentation.
14351            adj = ProcessList.FOREGROUND_APP_ADJ;
14352            schedGroup = Process.THREAD_GROUP_DEFAULT;
14353            app.adjType = "instrumentation";
14354            interesting = true;
14355            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14356        } else if ((queue = isReceivingBroadcast(app)) != null) {
14357            // An app that is currently receiving a broadcast also
14358            // counts as being in the foreground for OOM killer purposes.
14359            // It's placed in a sched group based on the nature of the
14360            // broadcast as reflected by which queue it's active in.
14361            adj = ProcessList.FOREGROUND_APP_ADJ;
14362            schedGroup = (queue == mFgBroadcastQueue)
14363                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14364            app.adjType = "broadcast";
14365            procState = ActivityManager.PROCESS_STATE_RECEIVER;
14366        } else if (app.executingServices.size() > 0) {
14367            // An app that is currently executing a service callback also
14368            // counts as being in the foreground.
14369            adj = ProcessList.FOREGROUND_APP_ADJ;
14370            schedGroup = app.execServicesFg ?
14371                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
14372            app.adjType = "exec-service";
14373            procState = ActivityManager.PROCESS_STATE_SERVICE;
14374            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
14375        } else {
14376            // As far as we know the process is empty.  We may change our mind later.
14377            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14378            // At this point we don't actually know the adjustment.  Use the cached adj
14379            // value that the caller wants us to.
14380            adj = cachedAdj;
14381            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14382            app.cached = true;
14383            app.empty = true;
14384            app.adjType = "cch-empty";
14385        }
14386
14387        // Examine all activities if not already foreground.
14388        if (!foregroundActivities && activitiesSize > 0) {
14389            for (int j = 0; j < activitiesSize; j++) {
14390                final ActivityRecord r = app.activities.get(j);
14391                if (r.app != app) {
14392                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
14393                            + app + "?!?");
14394                    continue;
14395                }
14396                if (r.visible) {
14397                    // App has a visible activity; only upgrade adjustment.
14398                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14399                        adj = ProcessList.VISIBLE_APP_ADJ;
14400                        app.adjType = "visible";
14401                    }
14402                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14403                        procState = ActivityManager.PROCESS_STATE_TOP;
14404                    }
14405                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14406                    app.cached = false;
14407                    app.empty = false;
14408                    foregroundActivities = true;
14409                    break;
14410                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
14411                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14412                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14413                        app.adjType = "pausing";
14414                    }
14415                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
14416                        procState = ActivityManager.PROCESS_STATE_TOP;
14417                    }
14418                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14419                    app.cached = false;
14420                    app.empty = false;
14421                    foregroundActivities = true;
14422                } else if (r.state == ActivityState.STOPPING) {
14423                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14424                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14425                        app.adjType = "stopping";
14426                    }
14427                    // For the process state, we will at this point consider the
14428                    // process to be cached.  It will be cached either as an activity
14429                    // or empty depending on whether the activity is finishing.  We do
14430                    // this so that we can treat the process as cached for purposes of
14431                    // memory trimming (determing current memory level, trim command to
14432                    // send to process) since there can be an arbitrary number of stopping
14433                    // processes and they should soon all go into the cached state.
14434                    if (!r.finishing) {
14435                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14436                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14437                        }
14438                    }
14439                    app.cached = false;
14440                    app.empty = false;
14441                    foregroundActivities = true;
14442                } else {
14443                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14444                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
14445                        app.adjType = "cch-act";
14446                    }
14447                }
14448            }
14449        }
14450
14451        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14452            if (app.foregroundServices) {
14453                // The user is aware of this app, so make it visible.
14454                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14455                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14456                app.cached = false;
14457                app.adjType = "fg-service";
14458                schedGroup = Process.THREAD_GROUP_DEFAULT;
14459            } else if (app.forcingToForeground != null) {
14460                // The user is aware of this app, so make it visible.
14461                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14462                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14463                app.cached = false;
14464                app.adjType = "force-fg";
14465                app.adjSource = app.forcingToForeground;
14466                schedGroup = Process.THREAD_GROUP_DEFAULT;
14467            }
14468        }
14469
14470        if (app.foregroundServices) {
14471            interesting = true;
14472        }
14473
14474        if (app == mHeavyWeightProcess) {
14475            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14476                // We don't want to kill the current heavy-weight process.
14477                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
14478                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14479                app.cached = false;
14480                app.adjType = "heavy";
14481            }
14482            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
14483                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
14484            }
14485        }
14486
14487        if (app == mHomeProcess) {
14488            if (adj > ProcessList.HOME_APP_ADJ) {
14489                // This process is hosting what we currently consider to be the
14490                // home app, so we don't want to let it go into the background.
14491                adj = ProcessList.HOME_APP_ADJ;
14492                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14493                app.cached = false;
14494                app.adjType = "home";
14495            }
14496            if (procState > ActivityManager.PROCESS_STATE_HOME) {
14497                procState = ActivityManager.PROCESS_STATE_HOME;
14498            }
14499        }
14500
14501        if (app == mPreviousProcess && app.activities.size() > 0) {
14502            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
14503                // This was the previous process that showed UI to the user.
14504                // We want to try to keep it around more aggressively, to give
14505                // a good experience around switching between two apps.
14506                adj = ProcessList.PREVIOUS_APP_ADJ;
14507                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14508                app.cached = false;
14509                app.adjType = "previous";
14510            }
14511            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
14512                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
14513            }
14514        }
14515
14516        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
14517                + " reason=" + app.adjType);
14518
14519        // By default, we use the computed adjustment.  It may be changed if
14520        // there are applications dependent on our services or providers, but
14521        // this gives us a baseline and makes sure we don't get into an
14522        // infinite recursion.
14523        app.adjSeq = mAdjSeq;
14524        app.curRawAdj = adj;
14525        app.hasStartedServices = false;
14526
14527        if (mBackupTarget != null && app == mBackupTarget.app) {
14528            // If possible we want to avoid killing apps while they're being backed up
14529            if (adj > ProcessList.BACKUP_APP_ADJ) {
14530                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
14531                adj = ProcessList.BACKUP_APP_ADJ;
14532                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14533                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14534                }
14535                app.adjType = "backup";
14536                app.cached = false;
14537            }
14538            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
14539                procState = ActivityManager.PROCESS_STATE_BACKUP;
14540            }
14541        }
14542
14543        boolean mayBeTop = false;
14544
14545        for (int is = app.services.size()-1;
14546                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14547                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14548                        || procState > ActivityManager.PROCESS_STATE_TOP);
14549                is--) {
14550            ServiceRecord s = app.services.valueAt(is);
14551            if (s.startRequested) {
14552                app.hasStartedServices = true;
14553                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
14554                    procState = ActivityManager.PROCESS_STATE_SERVICE;
14555                }
14556                if (app.hasShownUi && app != mHomeProcess) {
14557                    // If this process has shown some UI, let it immediately
14558                    // go to the LRU list because it may be pretty heavy with
14559                    // UI stuff.  We'll tag it with a label just to help
14560                    // debug and understand what is going on.
14561                    if (adj > ProcessList.SERVICE_ADJ) {
14562                        app.adjType = "cch-started-ui-services";
14563                    }
14564                } else {
14565                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14566                        // This service has seen some activity within
14567                        // recent memory, so we will keep its process ahead
14568                        // of the background processes.
14569                        if (adj > ProcessList.SERVICE_ADJ) {
14570                            adj = ProcessList.SERVICE_ADJ;
14571                            app.adjType = "started-services";
14572                            app.cached = false;
14573                        }
14574                    }
14575                    // If we have let the service slide into the background
14576                    // state, still have some text describing what it is doing
14577                    // even though the service no longer has an impact.
14578                    if (adj > ProcessList.SERVICE_ADJ) {
14579                        app.adjType = "cch-started-services";
14580                    }
14581                }
14582                // Don't kill this process because it is doing work; it
14583                // has said it is doing work.
14584                app.keeping = true;
14585            }
14586            for (int conni = s.connections.size()-1;
14587                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14588                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14589                            || procState > ActivityManager.PROCESS_STATE_TOP);
14590                    conni--) {
14591                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
14592                for (int i = 0;
14593                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
14594                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14595                                || procState > ActivityManager.PROCESS_STATE_TOP);
14596                        i++) {
14597                    // XXX should compute this based on the max of
14598                    // all connected clients.
14599                    ConnectionRecord cr = clist.get(i);
14600                    if (cr.binding.client == app) {
14601                        // Binding to ourself is not interesting.
14602                        continue;
14603                    }
14604                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
14605                        ProcessRecord client = cr.binding.client;
14606                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
14607                                TOP_APP, doingAll, now);
14608                        int clientProcState = client.curProcState;
14609                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14610                            // If the other app is cached for any reason, for purposes here
14611                            // we are going to consider it empty.  The specific cached state
14612                            // doesn't propagate except under certain conditions.
14613                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14614                        }
14615                        String adjType = null;
14616                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14617                            // Not doing bind OOM management, so treat
14618                            // this guy more like a started service.
14619                            if (app.hasShownUi && app != mHomeProcess) {
14620                                // If this process has shown some UI, let it immediately
14621                                // go to the LRU list because it may be pretty heavy with
14622                                // UI stuff.  We'll tag it with a label just to help
14623                                // debug and understand what is going on.
14624                                if (adj > clientAdj) {
14625                                    adjType = "cch-bound-ui-services";
14626                                }
14627                                app.cached = false;
14628                                clientAdj = adj;
14629                                clientProcState = procState;
14630                            } else {
14631                                if (now >= (s.lastActivity
14632                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
14633                                    // This service has not seen activity within
14634                                    // recent memory, so allow it to drop to the
14635                                    // LRU list if there is no other reason to keep
14636                                    // it around.  We'll also tag it with a label just
14637                                    // to help debug and undertand what is going on.
14638                                    if (adj > clientAdj) {
14639                                        adjType = "cch-bound-services";
14640                                    }
14641                                    clientAdj = adj;
14642                                }
14643                            }
14644                        }
14645                        if (adj > clientAdj) {
14646                            // If this process has recently shown UI, and
14647                            // the process that is binding to it is less
14648                            // important than being visible, then we don't
14649                            // care about the binding as much as we care
14650                            // about letting this process get into the LRU
14651                            // list to be killed and restarted if needed for
14652                            // memory.
14653                            if (app.hasShownUi && app != mHomeProcess
14654                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14655                                adjType = "cch-bound-ui-services";
14656                            } else {
14657                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14658                                        |Context.BIND_IMPORTANT)) != 0) {
14659                                    adj = clientAdj;
14660                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14661                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14662                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14663                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14664                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
14665                                    adj = clientAdj;
14666                                } else {
14667                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
14668                                        adj = ProcessList.VISIBLE_APP_ADJ;
14669                                    }
14670                                }
14671                                if (!client.cached) {
14672                                    app.cached = false;
14673                                }
14674                                if (client.keeping) {
14675                                    app.keeping = true;
14676                                }
14677                                adjType = "service";
14678                            }
14679                        }
14680                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14681                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14682                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14683                            }
14684                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14685                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14686                                    // Special handling of clients who are in the top state.
14687                                    // We *may* want to consider this process to be in the
14688                                    // top state as well, but only if there is not another
14689                                    // reason for it to be running.  Being on the top is a
14690                                    // special state, meaning you are specifically running
14691                                    // for the current top app.  If the process is already
14692                                    // running in the background for some other reason, it
14693                                    // is more important to continue considering it to be
14694                                    // in the background state.
14695                                    mayBeTop = true;
14696                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14697                                } else {
14698                                    // Special handling for above-top states (persistent
14699                                    // processes).  These should not bring the current process
14700                                    // into the top state, since they are not on top.  Instead
14701                                    // give them the best state after that.
14702                                    clientProcState =
14703                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14704                                }
14705                            }
14706                        } else {
14707                            if (clientProcState <
14708                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
14709                                clientProcState =
14710                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
14711                            }
14712                        }
14713                        if (procState > clientProcState) {
14714                            procState = clientProcState;
14715                        }
14716                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
14717                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
14718                            app.pendingUiClean = true;
14719                        }
14720                        if (adjType != null) {
14721                            app.adjType = adjType;
14722                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14723                                    .REASON_SERVICE_IN_USE;
14724                            app.adjSource = cr.binding.client;
14725                            app.adjSourceOom = clientAdj;
14726                            app.adjTarget = s.name;
14727                        }
14728                    }
14729                    final ActivityRecord a = cr.activity;
14730                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14731                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
14732                                (a.visible || a.state == ActivityState.RESUMED
14733                                 || a.state == ActivityState.PAUSING)) {
14734                            adj = ProcessList.FOREGROUND_APP_ADJ;
14735                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14736                                schedGroup = Process.THREAD_GROUP_DEFAULT;
14737                            }
14738                            app.cached = false;
14739                            app.adjType = "service";
14740                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14741                                    .REASON_SERVICE_IN_USE;
14742                            app.adjSource = a;
14743                            app.adjSourceOom = adj;
14744                            app.adjTarget = s.name;
14745                        }
14746                    }
14747                }
14748            }
14749        }
14750
14751        for (int provi = app.pubProviders.size()-1;
14752                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14753                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14754                        || procState > ActivityManager.PROCESS_STATE_TOP);
14755                provi--) {
14756            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
14757            for (int i = cpr.connections.size()-1;
14758                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14759                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
14760                            || procState > ActivityManager.PROCESS_STATE_TOP);
14761                    i--) {
14762                ContentProviderConnection conn = cpr.connections.get(i);
14763                ProcessRecord client = conn.client;
14764                if (client == app) {
14765                    // Being our own client is not interesting.
14766                    continue;
14767                }
14768                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
14769                int clientProcState = client.curProcState;
14770                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
14771                    // If the other app is cached for any reason, for purposes here
14772                    // we are going to consider it empty.
14773                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14774                }
14775                if (adj > clientAdj) {
14776                    if (app.hasShownUi && app != mHomeProcess
14777                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14778                        app.adjType = "cch-ui-provider";
14779                    } else {
14780                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14781                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14782                        app.adjType = "provider";
14783                    }
14784                    app.cached &= client.cached;
14785                    app.keeping |= client.keeping;
14786                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14787                            .REASON_PROVIDER_IN_USE;
14788                    app.adjSource = client;
14789                    app.adjSourceOom = clientAdj;
14790                    app.adjTarget = cpr.name;
14791                }
14792                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
14793                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
14794                        // Special handling of clients who are in the top state.
14795                        // We *may* want to consider this process to be in the
14796                        // top state as well, but only if there is not another
14797                        // reason for it to be running.  Being on the top is a
14798                        // special state, meaning you are specifically running
14799                        // for the current top app.  If the process is already
14800                        // running in the background for some other reason, it
14801                        // is more important to continue considering it to be
14802                        // in the background state.
14803                        mayBeTop = true;
14804                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14805                    } else {
14806                        // Special handling for above-top states (persistent
14807                        // processes).  These should not bring the current process
14808                        // into the top state, since they are not on top.  Instead
14809                        // give them the best state after that.
14810                        clientProcState =
14811                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14812                    }
14813                }
14814                if (procState > clientProcState) {
14815                    procState = clientProcState;
14816                }
14817                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14818                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14819                }
14820            }
14821            // If the provider has external (non-framework) process
14822            // dependencies, ensure that its adjustment is at least
14823            // FOREGROUND_APP_ADJ.
14824            if (cpr.hasExternalProcessHandles()) {
14825                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14826                    adj = ProcessList.FOREGROUND_APP_ADJ;
14827                    schedGroup = Process.THREAD_GROUP_DEFAULT;
14828                    app.cached = false;
14829                    app.keeping = true;
14830                    app.adjType = "provider";
14831                    app.adjTarget = cpr.name;
14832                }
14833                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
14834                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14835                }
14836            }
14837        }
14838
14839        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
14840            // A client of one of our services or providers is in the top state.  We
14841            // *may* want to be in the top state, but not if we are already running in
14842            // the background for some other reason.  For the decision here, we are going
14843            // to pick out a few specific states that we want to remain in when a client
14844            // is top (states that tend to be longer-term) and otherwise allow it to go
14845            // to the top state.
14846            switch (procState) {
14847                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
14848                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
14849                case ActivityManager.PROCESS_STATE_SERVICE:
14850                    // These all are longer-term states, so pull them up to the top
14851                    // of the background states, but not all the way to the top state.
14852                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
14853                    break;
14854                default:
14855                    // Otherwise, top is a better choice, so take it.
14856                    procState = ActivityManager.PROCESS_STATE_TOP;
14857                    break;
14858            }
14859        }
14860
14861        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
14862            // This is a cached process, but with client activities.  Mark it so.
14863            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
14864            app.adjType = "cch-client-act";
14865        }
14866
14867        if (adj == ProcessList.SERVICE_ADJ) {
14868            if (doingAll) {
14869                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
14870                mNewNumServiceProcs++;
14871                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
14872                if (!app.serviceb) {
14873                    // This service isn't far enough down on the LRU list to
14874                    // normally be a B service, but if we are low on RAM and it
14875                    // is large we want to force it down since we would prefer to
14876                    // keep launcher over it.
14877                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
14878                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
14879                        app.serviceHighRam = true;
14880                        app.serviceb = true;
14881                        //Slog.i(TAG, "ADJ " + app + " high ram!");
14882                    } else {
14883                        mNewNumAServiceProcs++;
14884                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
14885                    }
14886                } else {
14887                    app.serviceHighRam = false;
14888                }
14889            }
14890            if (app.serviceb) {
14891                adj = ProcessList.SERVICE_B_ADJ;
14892            }
14893        }
14894
14895        app.curRawAdj = adj;
14896
14897        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
14898        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14899        if (adj > app.maxAdj) {
14900            adj = app.maxAdj;
14901            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
14902                schedGroup = Process.THREAD_GROUP_DEFAULT;
14903            }
14904        }
14905        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
14906            app.keeping = true;
14907        }
14908
14909        // Do final modification to adj.  Everything we do between here and applying
14910        // the final setAdj must be done in this function, because we will also use
14911        // it when computing the final cached adj later.  Note that we don't need to
14912        // worry about this for max adj above, since max adj will always be used to
14913        // keep it out of the cached vaues.
14914        adj = app.modifyRawOomAdj(adj);
14915
14916        app.curProcState = procState;
14917
14918        int importance = app.memImportance;
14919        if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14920            app.curAdj = adj;
14921            app.curSchedGroup = schedGroup;
14922            if (!interesting) {
14923                // For this reporting, if there is not something explicitly
14924                // interesting in this process then we will push it to the
14925                // background importance.
14926                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14927            } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
14928                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14929            } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14930                importance =  ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14931            } else if (adj >= ProcessList.HOME_APP_ADJ) {
14932                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14933            } else if (adj >= ProcessList.SERVICE_ADJ) {
14934                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14935            } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14936                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14937            } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14938                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14939            } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14940                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14941            } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14942                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14943            } else {
14944                importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14945            }
14946        }
14947
14948        int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14949        if (foregroundActivities != app.foregroundActivities) {
14950            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14951        }
14952        if (changes != 0) {
14953            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14954            app.memImportance = importance;
14955            app.foregroundActivities = foregroundActivities;
14956            int i = mPendingProcessChanges.size()-1;
14957            ProcessChangeItem item = null;
14958            while (i >= 0) {
14959                item = mPendingProcessChanges.get(i);
14960                if (item.pid == app.pid) {
14961                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14962                    break;
14963                }
14964                i--;
14965            }
14966            if (i < 0) {
14967                // No existing item in pending changes; need a new one.
14968                final int NA = mAvailProcessChanges.size();
14969                if (NA > 0) {
14970                    item = mAvailProcessChanges.remove(NA-1);
14971                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14972                } else {
14973                    item = new ProcessChangeItem();
14974                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14975                }
14976                item.changes = 0;
14977                item.pid = app.pid;
14978                item.uid = app.info.uid;
14979                if (mPendingProcessChanges.size() == 0) {
14980                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14981                            "*** Enqueueing dispatch processes changed!");
14982                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14983                }
14984                mPendingProcessChanges.add(item);
14985            }
14986            item.changes |= changes;
14987            item.importance = importance;
14988            item.foregroundActivities = foregroundActivities;
14989            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14990                    + Integer.toHexString(System.identityHashCode(item))
14991                    + " " + app.toShortString() + ": changes=" + item.changes
14992                    + " importance=" + item.importance
14993                    + " foreground=" + item.foregroundActivities
14994                    + " type=" + app.adjType + " source=" + app.adjSource
14995                    + " target=" + app.adjTarget);
14996        }
14997
14998        return app.curRawAdj;
14999    }
15000
15001    /**
15002     * Schedule PSS collection of a process.
15003     */
15004    void requestPssLocked(ProcessRecord proc, int procState) {
15005        if (mPendingPssProcesses.contains(proc)) {
15006            return;
15007        }
15008        if (mPendingPssProcesses.size() == 0) {
15009            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15010        }
15011        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15012        proc.pssProcState = procState;
15013        mPendingPssProcesses.add(proc);
15014    }
15015
15016    /**
15017     * Schedule PSS collection of all processes.
15018     */
15019    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15020        if (!always) {
15021            if (now < (mLastFullPssTime +
15022                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15023                return;
15024            }
15025        }
15026        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15027        mLastFullPssTime = now;
15028        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15029        mPendingPssProcesses.clear();
15030        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15031            ProcessRecord app = mLruProcesses.get(i);
15032            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15033                app.pssProcState = app.setProcState;
15034                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15035                        mSleeping, now);
15036                mPendingPssProcesses.add(app);
15037            }
15038        }
15039        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15040    }
15041
15042    /**
15043     * Ask a given process to GC right now.
15044     */
15045    final void performAppGcLocked(ProcessRecord app) {
15046        try {
15047            app.lastRequestedGc = SystemClock.uptimeMillis();
15048            if (app.thread != null) {
15049                if (app.reportLowMemory) {
15050                    app.reportLowMemory = false;
15051                    app.thread.scheduleLowMemory();
15052                } else {
15053                    app.thread.processInBackground();
15054                }
15055            }
15056        } catch (Exception e) {
15057            // whatever.
15058        }
15059    }
15060
15061    /**
15062     * Returns true if things are idle enough to perform GCs.
15063     */
15064    private final boolean canGcNowLocked() {
15065        boolean processingBroadcasts = false;
15066        for (BroadcastQueue q : mBroadcastQueues) {
15067            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15068                processingBroadcasts = true;
15069            }
15070        }
15071        return !processingBroadcasts
15072                && (mSleeping || mStackSupervisor.allResumedActivitiesIdle());
15073    }
15074
15075    /**
15076     * Perform GCs on all processes that are waiting for it, but only
15077     * if things are idle.
15078     */
15079    final void performAppGcsLocked() {
15080        final int N = mProcessesToGc.size();
15081        if (N <= 0) {
15082            return;
15083        }
15084        if (canGcNowLocked()) {
15085            while (mProcessesToGc.size() > 0) {
15086                ProcessRecord proc = mProcessesToGc.remove(0);
15087                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15088                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15089                            <= SystemClock.uptimeMillis()) {
15090                        // To avoid spamming the system, we will GC processes one
15091                        // at a time, waiting a few seconds between each.
15092                        performAppGcLocked(proc);
15093                        scheduleAppGcsLocked();
15094                        return;
15095                    } else {
15096                        // It hasn't been long enough since we last GCed this
15097                        // process...  put it in the list to wait for its time.
15098                        addProcessToGcListLocked(proc);
15099                        break;
15100                    }
15101                }
15102            }
15103
15104            scheduleAppGcsLocked();
15105        }
15106    }
15107
15108    /**
15109     * If all looks good, perform GCs on all processes waiting for them.
15110     */
15111    final void performAppGcsIfAppropriateLocked() {
15112        if (canGcNowLocked()) {
15113            performAppGcsLocked();
15114            return;
15115        }
15116        // Still not idle, wait some more.
15117        scheduleAppGcsLocked();
15118    }
15119
15120    /**
15121     * Schedule the execution of all pending app GCs.
15122     */
15123    final void scheduleAppGcsLocked() {
15124        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15125
15126        if (mProcessesToGc.size() > 0) {
15127            // Schedule a GC for the time to the next process.
15128            ProcessRecord proc = mProcessesToGc.get(0);
15129            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15130
15131            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15132            long now = SystemClock.uptimeMillis();
15133            if (when < (now+GC_TIMEOUT)) {
15134                when = now + GC_TIMEOUT;
15135            }
15136            mHandler.sendMessageAtTime(msg, when);
15137        }
15138    }
15139
15140    /**
15141     * Add a process to the array of processes waiting to be GCed.  Keeps the
15142     * list in sorted order by the last GC time.  The process can't already be
15143     * on the list.
15144     */
15145    final void addProcessToGcListLocked(ProcessRecord proc) {
15146        boolean added = false;
15147        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15148            if (mProcessesToGc.get(i).lastRequestedGc <
15149                    proc.lastRequestedGc) {
15150                added = true;
15151                mProcessesToGc.add(i+1, proc);
15152                break;
15153            }
15154        }
15155        if (!added) {
15156            mProcessesToGc.add(0, proc);
15157        }
15158    }
15159
15160    /**
15161     * Set up to ask a process to GC itself.  This will either do it
15162     * immediately, or put it on the list of processes to gc the next
15163     * time things are idle.
15164     */
15165    final void scheduleAppGcLocked(ProcessRecord app) {
15166        long now = SystemClock.uptimeMillis();
15167        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15168            return;
15169        }
15170        if (!mProcessesToGc.contains(app)) {
15171            addProcessToGcListLocked(app);
15172            scheduleAppGcsLocked();
15173        }
15174    }
15175
15176    final void checkExcessivePowerUsageLocked(boolean doKills) {
15177        updateCpuStatsNow();
15178
15179        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15180        boolean doWakeKills = doKills;
15181        boolean doCpuKills = doKills;
15182        if (mLastPowerCheckRealtime == 0) {
15183            doWakeKills = false;
15184        }
15185        if (mLastPowerCheckUptime == 0) {
15186            doCpuKills = false;
15187        }
15188        if (stats.isScreenOn()) {
15189            doWakeKills = false;
15190        }
15191        final long curRealtime = SystemClock.elapsedRealtime();
15192        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15193        final long curUptime = SystemClock.uptimeMillis();
15194        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15195        mLastPowerCheckRealtime = curRealtime;
15196        mLastPowerCheckUptime = curUptime;
15197        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15198            doWakeKills = false;
15199        }
15200        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15201            doCpuKills = false;
15202        }
15203        int i = mLruProcesses.size();
15204        while (i > 0) {
15205            i--;
15206            ProcessRecord app = mLruProcesses.get(i);
15207            if (!app.keeping) {
15208                long wtime;
15209                synchronized (stats) {
15210                    wtime = stats.getProcessWakeTime(app.info.uid,
15211                            app.pid, curRealtime);
15212                }
15213                long wtimeUsed = wtime - app.lastWakeTime;
15214                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15215                if (DEBUG_POWER) {
15216                    StringBuilder sb = new StringBuilder(128);
15217                    sb.append("Wake for ");
15218                    app.toShortString(sb);
15219                    sb.append(": over ");
15220                    TimeUtils.formatDuration(realtimeSince, sb);
15221                    sb.append(" used ");
15222                    TimeUtils.formatDuration(wtimeUsed, sb);
15223                    sb.append(" (");
15224                    sb.append((wtimeUsed*100)/realtimeSince);
15225                    sb.append("%)");
15226                    Slog.i(TAG, sb.toString());
15227                    sb.setLength(0);
15228                    sb.append("CPU for ");
15229                    app.toShortString(sb);
15230                    sb.append(": over ");
15231                    TimeUtils.formatDuration(uptimeSince, sb);
15232                    sb.append(" used ");
15233                    TimeUtils.formatDuration(cputimeUsed, sb);
15234                    sb.append(" (");
15235                    sb.append((cputimeUsed*100)/uptimeSince);
15236                    sb.append("%)");
15237                    Slog.i(TAG, sb.toString());
15238                }
15239                // If a process has held a wake lock for more
15240                // than 50% of the time during this period,
15241                // that sounds bad.  Kill!
15242                if (doWakeKills && realtimeSince > 0
15243                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15244                    synchronized (stats) {
15245                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15246                                realtimeSince, wtimeUsed);
15247                    }
15248                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15249                            + " during " + realtimeSince);
15250                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15251                } else if (doCpuKills && uptimeSince > 0
15252                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15253                    synchronized (stats) {
15254                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15255                                uptimeSince, cputimeUsed);
15256                    }
15257                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15258                            + " during " + uptimeSince);
15259                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15260                } else {
15261                    app.lastWakeTime = wtime;
15262                    app.lastCpuTime = app.curCpuTime;
15263                }
15264            }
15265        }
15266    }
15267
15268    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15269            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15270        boolean success = true;
15271
15272        if (app.curRawAdj != app.setRawAdj) {
15273            if (wasKeeping && !app.keeping) {
15274                // This app is no longer something we want to keep.  Note
15275                // its current wake lock time to later know to kill it if
15276                // it is not behaving well.
15277                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15278                synchronized (stats) {
15279                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15280                            app.pid, SystemClock.elapsedRealtime());
15281                }
15282                app.lastCpuTime = app.curCpuTime;
15283            }
15284
15285            app.setRawAdj = app.curRawAdj;
15286        }
15287
15288        if (app.curAdj != app.setAdj) {
15289            ProcessList.setOomAdj(app.pid, app.curAdj);
15290            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15291                TAG, "Set " + app.pid + " " + app.processName +
15292                " adj " + app.curAdj + ": " + app.adjType);
15293            app.setAdj = app.curAdj;
15294        }
15295
15296        if (app.setSchedGroup != app.curSchedGroup) {
15297            app.setSchedGroup = app.curSchedGroup;
15298            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15299                    "Setting process group of " + app.processName
15300                    + " to " + app.curSchedGroup);
15301            if (app.waitingToKill != null &&
15302                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15303                killUnneededProcessLocked(app, app.waitingToKill);
15304                success = false;
15305            } else {
15306                if (true) {
15307                    long oldId = Binder.clearCallingIdentity();
15308                    try {
15309                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15310                    } catch (Exception e) {
15311                        Slog.w(TAG, "Failed setting process group of " + app.pid
15312                                + " to " + app.curSchedGroup);
15313                        e.printStackTrace();
15314                    } finally {
15315                        Binder.restoreCallingIdentity(oldId);
15316                    }
15317                } else {
15318                    if (app.thread != null) {
15319                        try {
15320                            app.thread.setSchedulingGroup(app.curSchedGroup);
15321                        } catch (RemoteException e) {
15322                        }
15323                    }
15324                }
15325                Process.setSwappiness(app.pid,
15326                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15327            }
15328        }
15329        if (app.repProcState != app.curProcState) {
15330            app.repProcState = app.curProcState;
15331            if (!reportingProcessState && app.thread != null) {
15332                try {
15333                    if (false) {
15334                        //RuntimeException h = new RuntimeException("here");
15335                        Slog.i(TAG, "Sending new process state " + app.repProcState
15336                                + " to " + app /*, h*/);
15337                    }
15338                    app.thread.setProcessState(app.repProcState);
15339                } catch (RemoteException e) {
15340                }
15341            }
15342        }
15343        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15344                app.setProcState)) {
15345            app.lastStateTime = now;
15346            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15347                    mSleeping, now);
15348            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15349                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15350                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15351                    + (app.nextPssTime-now) + ": " + app);
15352        } else {
15353            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15354                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15355                requestPssLocked(app, app.setProcState);
15356                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15357                        mSleeping, now);
15358            } else if (false && DEBUG_PSS) {
15359                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15360            }
15361        }
15362        if (app.setProcState != app.curProcState) {
15363            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15364                    "Proc state change of " + app.processName
15365                    + " to " + app.curProcState);
15366            app.setProcState = app.curProcState;
15367            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15368                app.notCachedSinceIdle = false;
15369            }
15370            if (!doingAll) {
15371                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15372            } else {
15373                app.procStateChanged = true;
15374            }
15375        }
15376        return success;
15377    }
15378
15379    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
15380        if (proc.thread != null && proc.baseProcessTracker != null) {
15381            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
15382        }
15383    }
15384
15385    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
15386            ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) {
15387        if (app.thread == null) {
15388            return false;
15389        }
15390
15391        final boolean wasKeeping = app.keeping;
15392
15393        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
15394
15395        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll,
15396                reportingProcessState, now);
15397    }
15398
15399    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
15400            boolean oomAdj) {
15401        if (isForeground != proc.foregroundServices) {
15402            proc.foregroundServices = isForeground;
15403            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
15404                    proc.info.uid);
15405            if (isForeground) {
15406                if (curProcs == null) {
15407                    curProcs = new ArrayList<ProcessRecord>();
15408                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
15409                }
15410                if (!curProcs.contains(proc)) {
15411                    curProcs.add(proc);
15412                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
15413                            proc.info.packageName, proc.info.uid);
15414                }
15415            } else {
15416                if (curProcs != null) {
15417                    if (curProcs.remove(proc)) {
15418                        mBatteryStatsService.noteEvent(
15419                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
15420                                proc.info.packageName, proc.info.uid);
15421                        if (curProcs.size() <= 0) {
15422                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
15423                        }
15424                    }
15425                }
15426            }
15427            if (oomAdj) {
15428                updateOomAdjLocked();
15429            }
15430        }
15431    }
15432
15433    private final ActivityRecord resumedAppLocked() {
15434        ActivityRecord act = mStackSupervisor.resumedAppLocked();
15435        String pkg;
15436        int uid;
15437        if (act != null) {
15438            pkg = act.packageName;
15439            uid = act.info.applicationInfo.uid;
15440        } else {
15441            pkg = null;
15442            uid = -1;
15443        }
15444        // Has the UID or resumed package name changed?
15445        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
15446                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
15447            if (mCurResumedPackage != null) {
15448                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
15449                        mCurResumedPackage, mCurResumedUid);
15450            }
15451            mCurResumedPackage = pkg;
15452            mCurResumedUid = uid;
15453            if (mCurResumedPackage != null) {
15454                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
15455                        mCurResumedPackage, mCurResumedUid);
15456            }
15457        }
15458        return act;
15459    }
15460
15461    final boolean updateOomAdjLocked(ProcessRecord app) {
15462        return updateOomAdjLocked(app, false);
15463    }
15464
15465    final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) {
15466        final ActivityRecord TOP_ACT = resumedAppLocked();
15467        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15468        final boolean wasCached = app.cached;
15469
15470        mAdjSeq++;
15471
15472        // This is the desired cached adjusment we want to tell it to use.
15473        // If our app is currently cached, we know it, and that is it.  Otherwise,
15474        // we don't know it yet, and it needs to now be cached we will then
15475        // need to do a complete oom adj.
15476        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
15477                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
15478        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState,
15479                SystemClock.uptimeMillis());
15480        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
15481            // Changed to/from cached state, so apps after it in the LRU
15482            // list may also be changed.
15483            updateOomAdjLocked();
15484        }
15485        return success;
15486    }
15487
15488    final void updateOomAdjLocked() {
15489        final ActivityRecord TOP_ACT = resumedAppLocked();
15490        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
15491        final long now = SystemClock.uptimeMillis();
15492        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
15493        final int N = mLruProcesses.size();
15494
15495        if (false) {
15496            RuntimeException e = new RuntimeException();
15497            e.fillInStackTrace();
15498            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
15499        }
15500
15501        mAdjSeq++;
15502        mNewNumServiceProcs = 0;
15503        mNewNumAServiceProcs = 0;
15504
15505        final int emptyProcessLimit;
15506        final int cachedProcessLimit;
15507        if (mProcessLimit <= 0) {
15508            emptyProcessLimit = cachedProcessLimit = 0;
15509        } else if (mProcessLimit == 1) {
15510            emptyProcessLimit = 1;
15511            cachedProcessLimit = 0;
15512        } else {
15513            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
15514            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
15515        }
15516
15517        // Let's determine how many processes we have running vs.
15518        // how many slots we have for background processes; we may want
15519        // to put multiple processes in a slot of there are enough of
15520        // them.
15521        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
15522                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
15523        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
15524        if (numEmptyProcs > cachedProcessLimit) {
15525            // If there are more empty processes than our limit on cached
15526            // processes, then use the cached process limit for the factor.
15527            // This ensures that the really old empty processes get pushed
15528            // down to the bottom, so if we are running low on memory we will
15529            // have a better chance at keeping around more cached processes
15530            // instead of a gazillion empty processes.
15531            numEmptyProcs = cachedProcessLimit;
15532        }
15533        int emptyFactor = numEmptyProcs/numSlots;
15534        if (emptyFactor < 1) emptyFactor = 1;
15535        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
15536        if (cachedFactor < 1) cachedFactor = 1;
15537        int stepCached = 0;
15538        int stepEmpty = 0;
15539        int numCached = 0;
15540        int numEmpty = 0;
15541        int numTrimming = 0;
15542
15543        mNumNonCachedProcs = 0;
15544        mNumCachedHiddenProcs = 0;
15545
15546        // First update the OOM adjustment for each of the
15547        // application processes based on their current state.
15548        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
15549        int nextCachedAdj = curCachedAdj+1;
15550        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
15551        int nextEmptyAdj = curEmptyAdj+2;
15552        for (int i=N-1; i>=0; i--) {
15553            ProcessRecord app = mLruProcesses.get(i);
15554            if (!app.killedByAm && app.thread != null) {
15555                app.procStateChanged = false;
15556                final boolean wasKeeping = app.keeping;
15557                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
15558
15559                // If we haven't yet assigned the final cached adj
15560                // to the process, do that now.
15561                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
15562                    switch (app.curProcState) {
15563                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15564                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15565                            // This process is a cached process holding activities...
15566                            // assign it the next cached value for that type, and then
15567                            // step that cached level.
15568                            app.curRawAdj = curCachedAdj;
15569                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
15570                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
15571                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
15572                                    + ")");
15573                            if (curCachedAdj != nextCachedAdj) {
15574                                stepCached++;
15575                                if (stepCached >= cachedFactor) {
15576                                    stepCached = 0;
15577                                    curCachedAdj = nextCachedAdj;
15578                                    nextCachedAdj += 2;
15579                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15580                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
15581                                    }
15582                                }
15583                            }
15584                            break;
15585                        default:
15586                            // For everything else, assign next empty cached process
15587                            // level and bump that up.  Note that this means that
15588                            // long-running services that have dropped down to the
15589                            // cached level will be treated as empty (since their process
15590                            // state is still as a service), which is what we want.
15591                            app.curRawAdj = curEmptyAdj;
15592                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
15593                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
15594                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
15595                                    + ")");
15596                            if (curEmptyAdj != nextEmptyAdj) {
15597                                stepEmpty++;
15598                                if (stepEmpty >= emptyFactor) {
15599                                    stepEmpty = 0;
15600                                    curEmptyAdj = nextEmptyAdj;
15601                                    nextEmptyAdj += 2;
15602                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
15603                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
15604                                    }
15605                                }
15606                            }
15607                            break;
15608                    }
15609                }
15610
15611                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now);
15612
15613                // Count the number of process types.
15614                switch (app.curProcState) {
15615                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
15616                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
15617                        mNumCachedHiddenProcs++;
15618                        numCached++;
15619                        if (numCached > cachedProcessLimit) {
15620                            killUnneededProcessLocked(app, "cached #" + numCached);
15621                        }
15622                        break;
15623                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
15624                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
15625                                && app.lastActivityTime < oldTime) {
15626                            killUnneededProcessLocked(app, "empty for "
15627                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
15628                                    / 1000) + "s");
15629                        } else {
15630                            numEmpty++;
15631                            if (numEmpty > emptyProcessLimit) {
15632                                killUnneededProcessLocked(app, "empty #" + numEmpty);
15633                            }
15634                        }
15635                        break;
15636                    default:
15637                        mNumNonCachedProcs++;
15638                        break;
15639                }
15640
15641                if (app.isolated && app.services.size() <= 0) {
15642                    // If this is an isolated process, and there are no
15643                    // services running in it, then the process is no longer
15644                    // needed.  We agressively kill these because we can by
15645                    // definition not re-use the same process again, and it is
15646                    // good to avoid having whatever code was running in them
15647                    // left sitting around after no longer needed.
15648                    killUnneededProcessLocked(app, "isolated not needed");
15649                }
15650
15651                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15652                        && !app.killedByAm) {
15653                    numTrimming++;
15654                }
15655            }
15656        }
15657
15658        mNumServiceProcs = mNewNumServiceProcs;
15659
15660        // Now determine the memory trimming level of background processes.
15661        // Unfortunately we need to start at the back of the list to do this
15662        // properly.  We only do this if the number of background apps we
15663        // are managing to keep around is less than half the maximum we desire;
15664        // if we are keeping a good number around, we'll let them use whatever
15665        // memory they want.
15666        final int numCachedAndEmpty = numCached + numEmpty;
15667        int memFactor;
15668        if (numCached <= ProcessList.TRIM_CACHED_APPS
15669                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
15670            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
15671                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
15672            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
15673                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
15674            } else {
15675                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
15676            }
15677        } else {
15678            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
15679        }
15680        // We always allow the memory level to go up (better).  We only allow it to go
15681        // down if we are in a state where that is allowed, *and* the total number of processes
15682        // has gone down since last time.
15683        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
15684                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
15685                + " last=" + mLastNumProcesses);
15686        if (memFactor > mLastMemoryLevel) {
15687            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
15688                memFactor = mLastMemoryLevel;
15689                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
15690            }
15691        }
15692        mLastMemoryLevel = memFactor;
15693        mLastNumProcesses = mLruProcesses.size();
15694        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now);
15695        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
15696        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
15697            if (mLowRamStartTime == 0) {
15698                mLowRamStartTime = now;
15699            }
15700            int step = 0;
15701            int fgTrimLevel;
15702            switch (memFactor) {
15703                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15704                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
15705                    break;
15706                case ProcessStats.ADJ_MEM_FACTOR_LOW:
15707                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
15708                    break;
15709                default:
15710                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
15711                    break;
15712            }
15713            int factor = numTrimming/3;
15714            int minFactor = 2;
15715            if (mHomeProcess != null) minFactor++;
15716            if (mPreviousProcess != null) minFactor++;
15717            if (factor < minFactor) factor = minFactor;
15718            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
15719            for (int i=N-1; i>=0; i--) {
15720                ProcessRecord app = mLruProcesses.get(i);
15721                if (allChanged || app.procStateChanged) {
15722                    setProcessTrackerState(app, trackerMemFactor, now);
15723                    app.procStateChanged = false;
15724                }
15725                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
15726                        && !app.killedByAm) {
15727                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
15728                        try {
15729                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15730                                    "Trimming memory of " + app.processName
15731                                    + " to " + curLevel);
15732                            app.thread.scheduleTrimMemory(curLevel);
15733                        } catch (RemoteException e) {
15734                        }
15735                        if (false) {
15736                            // For now we won't do this; our memory trimming seems
15737                            // to be good enough at this point that destroying
15738                            // activities causes more harm than good.
15739                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
15740                                    && app != mHomeProcess && app != mPreviousProcess) {
15741                                // Need to do this on its own message because the stack may not
15742                                // be in a consistent state at this point.
15743                                // For these apps we will also finish their activities
15744                                // to help them free memory.
15745                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
15746                            }
15747                        }
15748                    }
15749                    app.trimMemoryLevel = curLevel;
15750                    step++;
15751                    if (step >= factor) {
15752                        step = 0;
15753                        switch (curLevel) {
15754                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
15755                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
15756                                break;
15757                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
15758                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15759                                break;
15760                        }
15761                    }
15762                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15763                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
15764                            && app.thread != null) {
15765                        try {
15766                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15767                                    "Trimming memory of heavy-weight " + app.processName
15768                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15769                            app.thread.scheduleTrimMemory(
15770                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
15771                        } catch (RemoteException e) {
15772                        }
15773                    }
15774                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
15775                } else {
15776                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15777                            || app.systemNoUi) && app.pendingUiClean) {
15778                        // If this application is now in the background and it
15779                        // had done UI, then give it the special trim level to
15780                        // have it free UI resources.
15781                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
15782                        if (app.trimMemoryLevel < level && app.thread != null) {
15783                            try {
15784                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15785                                        "Trimming memory of bg-ui " + app.processName
15786                                        + " to " + level);
15787                                app.thread.scheduleTrimMemory(level);
15788                            } catch (RemoteException e) {
15789                            }
15790                        }
15791                        app.pendingUiClean = false;
15792                    }
15793                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
15794                        try {
15795                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15796                                    "Trimming memory of fg " + app.processName
15797                                    + " to " + fgTrimLevel);
15798                            app.thread.scheduleTrimMemory(fgTrimLevel);
15799                        } catch (RemoteException e) {
15800                        }
15801                    }
15802                    app.trimMemoryLevel = fgTrimLevel;
15803                }
15804            }
15805        } else {
15806            if (mLowRamStartTime != 0) {
15807                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
15808                mLowRamStartTime = 0;
15809            }
15810            for (int i=N-1; i>=0; i--) {
15811                ProcessRecord app = mLruProcesses.get(i);
15812                if (allChanged || app.procStateChanged) {
15813                    setProcessTrackerState(app, trackerMemFactor, now);
15814                    app.procStateChanged = false;
15815                }
15816                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15817                        || app.systemNoUi) && app.pendingUiClean) {
15818                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
15819                            && app.thread != null) {
15820                        try {
15821                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15822                                    "Trimming memory of ui hidden " + app.processName
15823                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15824                            app.thread.scheduleTrimMemory(
15825                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
15826                        } catch (RemoteException e) {
15827                        }
15828                    }
15829                    app.pendingUiClean = false;
15830                }
15831                app.trimMemoryLevel = 0;
15832            }
15833        }
15834
15835        if (mAlwaysFinishActivities) {
15836            // Need to do this on its own message because the stack may not
15837            // be in a consistent state at this point.
15838            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
15839        }
15840
15841        if (allChanged) {
15842            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
15843        }
15844
15845        if (mProcessStats.shouldWriteNowLocked(now)) {
15846            mHandler.post(new Runnable() {
15847                @Override public void run() {
15848                    synchronized (ActivityManagerService.this) {
15849                        mProcessStats.writeStateAsyncLocked();
15850                    }
15851                }
15852            });
15853        }
15854
15855        if (DEBUG_OOM_ADJ) {
15856            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
15857        }
15858    }
15859
15860    final void trimApplications() {
15861        synchronized (this) {
15862            int i;
15863
15864            // First remove any unused application processes whose package
15865            // has been removed.
15866            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
15867                final ProcessRecord app = mRemovedProcesses.get(i);
15868                if (app.activities.size() == 0
15869                        && app.curReceiver == null && app.services.size() == 0) {
15870                    Slog.i(
15871                        TAG, "Exiting empty application process "
15872                        + app.processName + " ("
15873                        + (app.thread != null ? app.thread.asBinder() : null)
15874                        + ")\n");
15875                    if (app.pid > 0 && app.pid != MY_PID) {
15876                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
15877                                app.processName, app.setAdj, "empty");
15878                        app.killedByAm = true;
15879                        Process.killProcessQuiet(app.pid);
15880                    } else {
15881                        try {
15882                            app.thread.scheduleExit();
15883                        } catch (Exception e) {
15884                            // Ignore exceptions.
15885                        }
15886                    }
15887                    cleanUpApplicationRecordLocked(app, false, true, -1);
15888                    mRemovedProcesses.remove(i);
15889
15890                    if (app.persistent) {
15891                        if (app.persistent) {
15892                            addAppLocked(app.info, false);
15893                        }
15894                    }
15895                }
15896            }
15897
15898            // Now update the oom adj for all processes.
15899            updateOomAdjLocked();
15900        }
15901    }
15902
15903    /** This method sends the specified signal to each of the persistent apps */
15904    public void signalPersistentProcesses(int sig) throws RemoteException {
15905        if (sig != Process.SIGNAL_USR1) {
15906            throw new SecurityException("Only SIGNAL_USR1 is allowed");
15907        }
15908
15909        synchronized (this) {
15910            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
15911                    != PackageManager.PERMISSION_GRANTED) {
15912                throw new SecurityException("Requires permission "
15913                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
15914            }
15915
15916            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15917                ProcessRecord r = mLruProcesses.get(i);
15918                if (r.thread != null && r.persistent) {
15919                    Process.sendSignal(r.pid, sig);
15920                }
15921            }
15922        }
15923    }
15924
15925    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
15926        if (proc == null || proc == mProfileProc) {
15927            proc = mProfileProc;
15928            path = mProfileFile;
15929            profileType = mProfileType;
15930            clearProfilerLocked();
15931        }
15932        if (proc == null) {
15933            return;
15934        }
15935        try {
15936            proc.thread.profilerControl(false, path, null, profileType);
15937        } catch (RemoteException e) {
15938            throw new IllegalStateException("Process disappeared");
15939        }
15940    }
15941
15942    private void clearProfilerLocked() {
15943        if (mProfileFd != null) {
15944            try {
15945                mProfileFd.close();
15946            } catch (IOException e) {
15947            }
15948        }
15949        mProfileApp = null;
15950        mProfileProc = null;
15951        mProfileFile = null;
15952        mProfileType = 0;
15953        mAutoStopProfiler = false;
15954    }
15955
15956    public boolean profileControl(String process, int userId, boolean start,
15957            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
15958
15959        try {
15960            synchronized (this) {
15961                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15962                // its own permission.
15963                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15964                        != PackageManager.PERMISSION_GRANTED) {
15965                    throw new SecurityException("Requires permission "
15966                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15967                }
15968
15969                if (start && fd == null) {
15970                    throw new IllegalArgumentException("null fd");
15971                }
15972
15973                ProcessRecord proc = null;
15974                if (process != null) {
15975                    proc = findProcessLocked(process, userId, "profileControl");
15976                }
15977
15978                if (start && (proc == null || proc.thread == null)) {
15979                    throw new IllegalArgumentException("Unknown process: " + process);
15980                }
15981
15982                if (start) {
15983                    stopProfilerLocked(null, null, 0);
15984                    setProfileApp(proc.info, proc.processName, path, fd, false);
15985                    mProfileProc = proc;
15986                    mProfileType = profileType;
15987                    try {
15988                        fd = fd.dup();
15989                    } catch (IOException e) {
15990                        fd = null;
15991                    }
15992                    proc.thread.profilerControl(start, path, fd, profileType);
15993                    fd = null;
15994                    mProfileFd = null;
15995                } else {
15996                    stopProfilerLocked(proc, path, profileType);
15997                    if (fd != null) {
15998                        try {
15999                            fd.close();
16000                        } catch (IOException e) {
16001                        }
16002                    }
16003                }
16004
16005                return true;
16006            }
16007        } catch (RemoteException e) {
16008            throw new IllegalStateException("Process disappeared");
16009        } finally {
16010            if (fd != null) {
16011                try {
16012                    fd.close();
16013                } catch (IOException e) {
16014                }
16015            }
16016        }
16017    }
16018
16019    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16020        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16021                userId, true, true, callName, null);
16022        ProcessRecord proc = null;
16023        try {
16024            int pid = Integer.parseInt(process);
16025            synchronized (mPidsSelfLocked) {
16026                proc = mPidsSelfLocked.get(pid);
16027            }
16028        } catch (NumberFormatException e) {
16029        }
16030
16031        if (proc == null) {
16032            ArrayMap<String, SparseArray<ProcessRecord>> all
16033                    = mProcessNames.getMap();
16034            SparseArray<ProcessRecord> procs = all.get(process);
16035            if (procs != null && procs.size() > 0) {
16036                proc = procs.valueAt(0);
16037                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16038                    for (int i=1; i<procs.size(); i++) {
16039                        ProcessRecord thisProc = procs.valueAt(i);
16040                        if (thisProc.userId == userId) {
16041                            proc = thisProc;
16042                            break;
16043                        }
16044                    }
16045                }
16046            }
16047        }
16048
16049        return proc;
16050    }
16051
16052    public boolean dumpHeap(String process, int userId, boolean managed,
16053            String path, ParcelFileDescriptor fd) throws RemoteException {
16054
16055        try {
16056            synchronized (this) {
16057                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16058                // its own permission (same as profileControl).
16059                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16060                        != PackageManager.PERMISSION_GRANTED) {
16061                    throw new SecurityException("Requires permission "
16062                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16063                }
16064
16065                if (fd == null) {
16066                    throw new IllegalArgumentException("null fd");
16067                }
16068
16069                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16070                if (proc == null || proc.thread == null) {
16071                    throw new IllegalArgumentException("Unknown process: " + process);
16072                }
16073
16074                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16075                if (!isDebuggable) {
16076                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16077                        throw new SecurityException("Process not debuggable: " + proc);
16078                    }
16079                }
16080
16081                proc.thread.dumpHeap(managed, path, fd);
16082                fd = null;
16083                return true;
16084            }
16085        } catch (RemoteException e) {
16086            throw new IllegalStateException("Process disappeared");
16087        } finally {
16088            if (fd != null) {
16089                try {
16090                    fd.close();
16091                } catch (IOException e) {
16092                }
16093            }
16094        }
16095    }
16096
16097    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16098    public void monitor() {
16099        synchronized (this) { }
16100    }
16101
16102    void onCoreSettingsChange(Bundle settings) {
16103        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16104            ProcessRecord processRecord = mLruProcesses.get(i);
16105            try {
16106                if (processRecord.thread != null) {
16107                    processRecord.thread.setCoreSettings(settings);
16108                }
16109            } catch (RemoteException re) {
16110                /* ignore */
16111            }
16112        }
16113    }
16114
16115    // Multi-user methods
16116
16117    /**
16118     * Start user, if its not already running, but don't bring it to foreground.
16119     */
16120    @Override
16121    public boolean startUserInBackground(final int userId) {
16122        return startUser(userId, /* foreground */ false);
16123    }
16124
16125    @Override
16126    public boolean switchUser(final int userId) {
16127        return startUser(userId, /* foregound */ true);
16128    }
16129
16130    private boolean startUser(final int userId, boolean foreground) {
16131        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16132                != PackageManager.PERMISSION_GRANTED) {
16133            String msg = "Permission Denial: switchUser() from pid="
16134                    + Binder.getCallingPid()
16135                    + ", uid=" + Binder.getCallingUid()
16136                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16137            Slog.w(TAG, msg);
16138            throw new SecurityException(msg);
16139        }
16140
16141        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16142
16143        final long ident = Binder.clearCallingIdentity();
16144        try {
16145            synchronized (this) {
16146                final int oldUserId = mCurrentUserId;
16147                if (oldUserId == userId) {
16148                    return true;
16149                }
16150
16151                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16152                if (userInfo == null) {
16153                    Slog.w(TAG, "No user info for user #" + userId);
16154                    return false;
16155                }
16156
16157                if (foreground) {
16158                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16159                            R.anim.screen_user_enter);
16160                }
16161
16162                boolean needStart = false;
16163
16164                // If the user we are switching to is not currently started, then
16165                // we need to start it now.
16166                if (mStartedUsers.get(userId) == null) {
16167                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16168                    updateStartedUserArrayLocked();
16169                    needStart = true;
16170                }
16171
16172                final Integer userIdInt = Integer.valueOf(userId);
16173                mUserLru.remove(userIdInt);
16174                mUserLru.add(userIdInt);
16175
16176                if (foreground) {
16177                    mCurrentUserId = userId;
16178                    mWindowManager.setCurrentUser(userId);
16179                    // Once the internal notion of the active user has switched, we lock the device
16180                    // with the option to show the user switcher on the keyguard.
16181                    mWindowManager.lockNow(null);
16182                } else {
16183                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16184                    mUserLru.remove(currentUserIdInt);
16185                    mUserLru.add(currentUserIdInt);
16186                }
16187
16188                final UserStartedState uss = mStartedUsers.get(userId);
16189
16190                // Make sure user is in the started state.  If it is currently
16191                // stopping, we need to knock that off.
16192                if (uss.mState == UserStartedState.STATE_STOPPING) {
16193                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16194                    // so we can just fairly silently bring the user back from
16195                    // the almost-dead.
16196                    uss.mState = UserStartedState.STATE_RUNNING;
16197                    updateStartedUserArrayLocked();
16198                    needStart = true;
16199                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16200                    // This means ACTION_SHUTDOWN has been sent, so we will
16201                    // need to treat this as a new boot of the user.
16202                    uss.mState = UserStartedState.STATE_BOOTING;
16203                    updateStartedUserArrayLocked();
16204                    needStart = true;
16205                }
16206
16207                if (foreground) {
16208                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16209                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16210                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16211                            oldUserId, userId, uss));
16212                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16213                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16214                }
16215
16216                if (needStart) {
16217                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16218                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16219                            | Intent.FLAG_RECEIVER_FOREGROUND);
16220                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16221                    broadcastIntentLocked(null, null, intent,
16222                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16223                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16224                }
16225
16226                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16227                    if (userId != 0) {
16228                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16229                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16230                        broadcastIntentLocked(null, null, intent, null,
16231                                new IIntentReceiver.Stub() {
16232                                    public void performReceive(Intent intent, int resultCode,
16233                                            String data, Bundle extras, boolean ordered,
16234                                            boolean sticky, int sendingUser) {
16235                                        userInitialized(uss, userId);
16236                                    }
16237                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16238                                true, false, MY_PID, Process.SYSTEM_UID,
16239                                userId);
16240                        uss.initializing = true;
16241                    } else {
16242                        getUserManagerLocked().makeInitialized(userInfo.id);
16243                    }
16244                }
16245
16246                if (foreground) {
16247                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16248                    if (homeInFront) {
16249                        startHomeActivityLocked(userId);
16250                    } else {
16251                        mStackSupervisor.resumeTopActivitiesLocked();
16252                    }
16253                    EventLogTags.writeAmSwitchUser(userId);
16254                    getUserManagerLocked().userForeground(userId);
16255                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16256                }
16257
16258                if (needStart) {
16259                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16260                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16261                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16262                    broadcastIntentLocked(null, null, intent,
16263                            null, new IIntentReceiver.Stub() {
16264                                @Override
16265                                public void performReceive(Intent intent, int resultCode, String data,
16266                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16267                                        throws RemoteException {
16268                                }
16269                            }, 0, null, null,
16270                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16271                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16272                }
16273            }
16274        } finally {
16275            Binder.restoreCallingIdentity(ident);
16276        }
16277
16278        return true;
16279    }
16280
16281    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16282        long ident = Binder.clearCallingIdentity();
16283        try {
16284            Intent intent;
16285            if (oldUserId >= 0) {
16286                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16287                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16288                        | Intent.FLAG_RECEIVER_FOREGROUND);
16289                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16290                broadcastIntentLocked(null, null, intent,
16291                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16292                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16293            }
16294            if (newUserId >= 0) {
16295                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16296                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16297                        | Intent.FLAG_RECEIVER_FOREGROUND);
16298                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16299                broadcastIntentLocked(null, null, intent,
16300                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16301                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16302                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16303                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16304                        | Intent.FLAG_RECEIVER_FOREGROUND);
16305                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16306                broadcastIntentLocked(null, null, intent,
16307                        null, null, 0, null, null,
16308                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16309                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16310            }
16311        } finally {
16312            Binder.restoreCallingIdentity(ident);
16313        }
16314    }
16315
16316    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16317            final int newUserId) {
16318        final int N = mUserSwitchObservers.beginBroadcast();
16319        if (N > 0) {
16320            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16321                int mCount = 0;
16322                @Override
16323                public void sendResult(Bundle data) throws RemoteException {
16324                    synchronized (ActivityManagerService.this) {
16325                        if (mCurUserSwitchCallback == this) {
16326                            mCount++;
16327                            if (mCount == N) {
16328                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16329                            }
16330                        }
16331                    }
16332                }
16333            };
16334            synchronized (this) {
16335                uss.switching = true;
16336                mCurUserSwitchCallback = callback;
16337            }
16338            for (int i=0; i<N; i++) {
16339                try {
16340                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
16341                            newUserId, callback);
16342                } catch (RemoteException e) {
16343                }
16344            }
16345        } else {
16346            synchronized (this) {
16347                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16348            }
16349        }
16350        mUserSwitchObservers.finishBroadcast();
16351    }
16352
16353    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16354        synchronized (this) {
16355            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
16356            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16357        }
16358    }
16359
16360    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
16361        mCurUserSwitchCallback = null;
16362        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16363        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
16364                oldUserId, newUserId, uss));
16365    }
16366
16367    void userInitialized(UserStartedState uss, int newUserId) {
16368        completeSwitchAndInitalize(uss, newUserId, true, false);
16369    }
16370
16371    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
16372        completeSwitchAndInitalize(uss, newUserId, false, true);
16373    }
16374
16375    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
16376            boolean clearInitializing, boolean clearSwitching) {
16377        boolean unfrozen = false;
16378        synchronized (this) {
16379            if (clearInitializing) {
16380                uss.initializing = false;
16381                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
16382            }
16383            if (clearSwitching) {
16384                uss.switching = false;
16385            }
16386            if (!uss.switching && !uss.initializing) {
16387                mWindowManager.stopFreezingScreen();
16388                unfrozen = true;
16389            }
16390        }
16391        if (unfrozen) {
16392            final int N = mUserSwitchObservers.beginBroadcast();
16393            for (int i=0; i<N; i++) {
16394                try {
16395                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
16396                } catch (RemoteException e) {
16397                }
16398            }
16399            mUserSwitchObservers.finishBroadcast();
16400        }
16401    }
16402
16403    void scheduleStartRelatedUsersLocked() {
16404        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
16405            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
16406                    DateUtils.SECOND_IN_MILLIS);
16407        }
16408    }
16409
16410    void startRelatedUsersLocked() {
16411        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
16412        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
16413        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
16414        for (UserInfo relatedUser : relatedUsers) {
16415            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
16416                toStart.add(relatedUser);
16417            }
16418        }
16419        final int n = toStart.size();
16420        int i = 0;
16421        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
16422            startUserInBackground(toStart.get(i).id);
16423        }
16424        if (i < n) {
16425            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
16426        }
16427    }
16428
16429    void finishUserSwitch(UserStartedState uss) {
16430        synchronized (this) {
16431            if (uss.mState == UserStartedState.STATE_BOOTING
16432                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
16433                uss.mState = UserStartedState.STATE_RUNNING;
16434                final int userId = uss.mHandle.getIdentifier();
16435                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
16436                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16437                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
16438                broadcastIntentLocked(null, null, intent,
16439                        null, null, 0, null, null,
16440                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
16441                        true, false, MY_PID, Process.SYSTEM_UID, userId);
16442            }
16443
16444            startRelatedUsersLocked();
16445
16446            int num = mUserLru.size();
16447            int i = 0;
16448            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
16449                Integer oldUserId = mUserLru.get(i);
16450                UserStartedState oldUss = mStartedUsers.get(oldUserId);
16451                if (oldUss == null) {
16452                    // Shouldn't happen, but be sane if it does.
16453                    mUserLru.remove(i);
16454                    num--;
16455                    continue;
16456                }
16457                if (oldUss.mState == UserStartedState.STATE_STOPPING
16458                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
16459                    // This user is already stopping, doesn't count.
16460                    num--;
16461                    i++;
16462                    continue;
16463                }
16464                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
16465                    // Owner and current can't be stopped, but count as running.
16466                    i++;
16467                    continue;
16468                }
16469                // This is a user to be stopped.
16470                stopUserLocked(oldUserId, null);
16471                num--;
16472                i++;
16473            }
16474        }
16475    }
16476
16477    @Override
16478    public int stopUser(final int userId, final IStopUserCallback callback) {
16479        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16480                != PackageManager.PERMISSION_GRANTED) {
16481            String msg = "Permission Denial: switchUser() from pid="
16482                    + Binder.getCallingPid()
16483                    + ", uid=" + Binder.getCallingUid()
16484                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16485            Slog.w(TAG, msg);
16486            throw new SecurityException(msg);
16487        }
16488        if (userId <= 0) {
16489            throw new IllegalArgumentException("Can't stop primary user " + userId);
16490        }
16491        synchronized (this) {
16492            return stopUserLocked(userId, callback);
16493        }
16494    }
16495
16496    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
16497        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
16498        if (mCurrentUserId == userId) {
16499            return ActivityManager.USER_OP_IS_CURRENT;
16500        }
16501
16502        final UserStartedState uss = mStartedUsers.get(userId);
16503        if (uss == null) {
16504            // User is not started, nothing to do...  but we do need to
16505            // callback if requested.
16506            if (callback != null) {
16507                mHandler.post(new Runnable() {
16508                    @Override
16509                    public void run() {
16510                        try {
16511                            callback.userStopped(userId);
16512                        } catch (RemoteException e) {
16513                        }
16514                    }
16515                });
16516            }
16517            return ActivityManager.USER_OP_SUCCESS;
16518        }
16519
16520        if (callback != null) {
16521            uss.mStopCallbacks.add(callback);
16522        }
16523
16524        if (uss.mState != UserStartedState.STATE_STOPPING
16525                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16526            uss.mState = UserStartedState.STATE_STOPPING;
16527            updateStartedUserArrayLocked();
16528
16529            long ident = Binder.clearCallingIdentity();
16530            try {
16531                // We are going to broadcast ACTION_USER_STOPPING and then
16532                // once that is done send a final ACTION_SHUTDOWN and then
16533                // stop the user.
16534                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
16535                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16536                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16537                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
16538                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
16539                // This is the result receiver for the final shutdown broadcast.
16540                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
16541                    @Override
16542                    public void performReceive(Intent intent, int resultCode, String data,
16543                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16544                        finishUserStop(uss);
16545                    }
16546                };
16547                // This is the result receiver for the initial stopping broadcast.
16548                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
16549                    @Override
16550                    public void performReceive(Intent intent, int resultCode, String data,
16551                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
16552                        // On to the next.
16553                        synchronized (ActivityManagerService.this) {
16554                            if (uss.mState != UserStartedState.STATE_STOPPING) {
16555                                // Whoops, we are being started back up.  Abort, abort!
16556                                return;
16557                            }
16558                            uss.mState = UserStartedState.STATE_SHUTDOWN;
16559                        }
16560                        broadcastIntentLocked(null, null, shutdownIntent,
16561                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
16562                                true, false, MY_PID, Process.SYSTEM_UID, userId);
16563                    }
16564                };
16565                // Kick things off.
16566                broadcastIntentLocked(null, null, stoppingIntent,
16567                        null, stoppingReceiver, 0, null, null,
16568                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16569                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16570            } finally {
16571                Binder.restoreCallingIdentity(ident);
16572            }
16573        }
16574
16575        return ActivityManager.USER_OP_SUCCESS;
16576    }
16577
16578    void finishUserStop(UserStartedState uss) {
16579        final int userId = uss.mHandle.getIdentifier();
16580        boolean stopped;
16581        ArrayList<IStopUserCallback> callbacks;
16582        synchronized (this) {
16583            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
16584            if (mStartedUsers.get(userId) != uss) {
16585                stopped = false;
16586            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
16587                stopped = false;
16588            } else {
16589                stopped = true;
16590                // User can no longer run.
16591                mStartedUsers.remove(userId);
16592                mUserLru.remove(Integer.valueOf(userId));
16593                updateStartedUserArrayLocked();
16594
16595                // Clean up all state and processes associated with the user.
16596                // Kill all the processes for the user.
16597                forceStopUserLocked(userId, "finish user");
16598            }
16599        }
16600
16601        for (int i=0; i<callbacks.size(); i++) {
16602            try {
16603                if (stopped) callbacks.get(i).userStopped(userId);
16604                else callbacks.get(i).userStopAborted(userId);
16605            } catch (RemoteException e) {
16606            }
16607        }
16608
16609        mStackSupervisor.removeUserLocked(userId);
16610    }
16611
16612    @Override
16613    public UserInfo getCurrentUser() {
16614        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16615                != PackageManager.PERMISSION_GRANTED) && (
16616                checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16617                != PackageManager.PERMISSION_GRANTED)) {
16618            String msg = "Permission Denial: getCurrentUser() from pid="
16619                    + Binder.getCallingPid()
16620                    + ", uid=" + Binder.getCallingUid()
16621                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16622            Slog.w(TAG, msg);
16623            throw new SecurityException(msg);
16624        }
16625        synchronized (this) {
16626            return getUserManagerLocked().getUserInfo(mCurrentUserId);
16627        }
16628    }
16629
16630    int getCurrentUserIdLocked() {
16631        return mCurrentUserId;
16632    }
16633
16634    @Override
16635    public boolean isUserRunning(int userId, boolean orStopped) {
16636        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16637                != PackageManager.PERMISSION_GRANTED) {
16638            String msg = "Permission Denial: isUserRunning() from pid="
16639                    + Binder.getCallingPid()
16640                    + ", uid=" + Binder.getCallingUid()
16641                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16642            Slog.w(TAG, msg);
16643            throw new SecurityException(msg);
16644        }
16645        synchronized (this) {
16646            return isUserRunningLocked(userId, orStopped);
16647        }
16648    }
16649
16650    boolean isUserRunningLocked(int userId, boolean orStopped) {
16651        UserStartedState state = mStartedUsers.get(userId);
16652        if (state == null) {
16653            return false;
16654        }
16655        if (orStopped) {
16656            return true;
16657        }
16658        return state.mState != UserStartedState.STATE_STOPPING
16659                && state.mState != UserStartedState.STATE_SHUTDOWN;
16660    }
16661
16662    @Override
16663    public int[] getRunningUserIds() {
16664        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
16665                != PackageManager.PERMISSION_GRANTED) {
16666            String msg = "Permission Denial: isUserRunning() from pid="
16667                    + Binder.getCallingPid()
16668                    + ", uid=" + Binder.getCallingUid()
16669                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
16670            Slog.w(TAG, msg);
16671            throw new SecurityException(msg);
16672        }
16673        synchronized (this) {
16674            return mStartedUserArray;
16675        }
16676    }
16677
16678    private void updateStartedUserArrayLocked() {
16679        int num = 0;
16680        for (int i=0; i<mStartedUsers.size();  i++) {
16681            UserStartedState uss = mStartedUsers.valueAt(i);
16682            // This list does not include stopping users.
16683            if (uss.mState != UserStartedState.STATE_STOPPING
16684                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16685                num++;
16686            }
16687        }
16688        mStartedUserArray = new int[num];
16689        num = 0;
16690        for (int i=0; i<mStartedUsers.size();  i++) {
16691            UserStartedState uss = mStartedUsers.valueAt(i);
16692            if (uss.mState != UserStartedState.STATE_STOPPING
16693                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
16694                mStartedUserArray[num] = mStartedUsers.keyAt(i);
16695                num++;
16696            }
16697        }
16698    }
16699
16700    @Override
16701    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
16702        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
16703                != PackageManager.PERMISSION_GRANTED) {
16704            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
16705                    + Binder.getCallingPid()
16706                    + ", uid=" + Binder.getCallingUid()
16707                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
16708            Slog.w(TAG, msg);
16709            throw new SecurityException(msg);
16710        }
16711
16712        mUserSwitchObservers.register(observer);
16713    }
16714
16715    @Override
16716    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
16717        mUserSwitchObservers.unregister(observer);
16718    }
16719
16720    private boolean userExists(int userId) {
16721        if (userId == 0) {
16722            return true;
16723        }
16724        UserManagerService ums = getUserManagerLocked();
16725        return ums != null ? (ums.getUserInfo(userId) != null) : false;
16726    }
16727
16728    int[] getUsersLocked() {
16729        UserManagerService ums = getUserManagerLocked();
16730        return ums != null ? ums.getUserIds() : new int[] { 0 };
16731    }
16732
16733    UserManagerService getUserManagerLocked() {
16734        if (mUserManager == null) {
16735            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
16736            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
16737        }
16738        return mUserManager;
16739    }
16740
16741    private int applyUserId(int uid, int userId) {
16742        return UserHandle.getUid(userId, uid);
16743    }
16744
16745    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
16746        if (info == null) return null;
16747        ApplicationInfo newInfo = new ApplicationInfo(info);
16748        newInfo.uid = applyUserId(info.uid, userId);
16749        newInfo.dataDir = USER_DATA_DIR + userId + "/"
16750                + info.packageName;
16751        return newInfo;
16752    }
16753
16754    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
16755        if (aInfo == null
16756                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
16757            return aInfo;
16758        }
16759
16760        ActivityInfo info = new ActivityInfo(aInfo);
16761        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
16762        return info;
16763    }
16764}
16765