ActivityManagerService.java revision 04d480e1c338a921a8659e165d74f8437785acc1
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.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.content.DialogInterface.OnClickListener;
40import android.content.res.Resources;
41import android.graphics.BitmapFactory;
42import android.graphics.Rect;
43import android.os.BatteryStats;
44import android.os.PersistableBundle;
45import android.service.voice.IVoiceInteractionSession;
46import android.util.ArrayMap;
47
48import com.android.internal.R;
49import com.android.internal.annotations.GuardedBy;
50import com.android.internal.app.IAppOpsService;
51import com.android.internal.app.IVoiceInteractor;
52import com.android.internal.app.ProcessMap;
53import com.android.internal.app.ProcessStats;
54import com.android.internal.content.PackageMonitor;
55import com.android.internal.os.BackgroundThread;
56import com.android.internal.os.BatteryStatsImpl;
57import com.android.internal.os.ProcessCpuTracker;
58import com.android.internal.os.TransferPipe;
59import com.android.internal.os.Zygote;
60import com.android.internal.util.FastPrintWriter;
61import com.android.internal.util.FastXmlSerializer;
62import com.android.internal.util.MemInfoReader;
63import com.android.internal.util.Preconditions;
64import com.android.server.AppOpsService;
65import com.android.server.AttributeCache;
66import com.android.server.IntentResolver;
67import com.android.server.LocalServices;
68import com.android.server.ServiceThread;
69import com.android.server.SystemService;
70import com.android.server.SystemServiceManager;
71import com.android.server.Watchdog;
72import com.android.server.am.ActivityStack.ActivityState;
73import com.android.server.firewall.IntentFirewall;
74import com.android.server.pm.UserManagerService;
75import com.android.server.wm.AppTransition;
76import com.android.server.wm.WindowManagerService;
77import com.google.android.collect.Lists;
78import com.google.android.collect.Maps;
79
80import libcore.io.IoUtils;
81
82import org.xmlpull.v1.XmlPullParser;
83import org.xmlpull.v1.XmlPullParserException;
84import org.xmlpull.v1.XmlSerializer;
85
86import android.app.Activity;
87import android.app.ActivityManager;
88import android.app.ActivityManager.RunningTaskInfo;
89import android.app.ActivityManager.StackInfo;
90import android.app.ActivityManagerInternal;
91import android.app.ActivityManagerNative;
92import android.app.ActivityOptions;
93import android.app.ActivityThread;
94import android.app.AlertDialog;
95import android.app.AppGlobals;
96import android.app.ApplicationErrorReport;
97import android.app.Dialog;
98import android.app.IActivityController;
99import android.app.IApplicationThread;
100import android.app.IInstrumentationWatcher;
101import android.app.INotificationManager;
102import android.app.IProcessObserver;
103import android.app.IServiceConnection;
104import android.app.IStopUserCallback;
105import android.app.IUiAutomationConnection;
106import android.app.IUserSwitchObserver;
107import android.app.Instrumentation;
108import android.app.Notification;
109import android.app.NotificationManager;
110import android.app.PendingIntent;
111import android.app.backup.IBackupManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.ParceledListSlice;
136import android.content.pm.UserInfo;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PathPermission;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.res.CompatibilityInfo;
143import android.content.res.Configuration;
144import android.graphics.Bitmap;
145import android.net.Proxy;
146import android.net.ProxyInfo;
147import android.net.Uri;
148import android.os.Binder;
149import android.os.Build;
150import android.os.Bundle;
151import android.os.Debug;
152import android.os.DropBoxManager;
153import android.os.Environment;
154import android.os.FactoryTest;
155import android.os.FileObserver;
156import android.os.FileUtils;
157import android.os.Handler;
158import android.os.IBinder;
159import android.os.IPermissionController;
160import android.os.IRemoteCallback;
161import android.os.IUserManager;
162import android.os.Looper;
163import android.os.Message;
164import android.os.Parcel;
165import android.os.ParcelFileDescriptor;
166import android.os.Process;
167import android.os.RemoteCallbackList;
168import android.os.RemoteException;
169import android.os.SELinux;
170import android.os.ServiceManager;
171import android.os.StrictMode;
172import android.os.SystemClock;
173import android.os.SystemProperties;
174import android.os.UpdateLock;
175import android.os.UserHandle;
176import android.provider.Settings;
177import android.text.Spannable;
178import android.text.SpannableString;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.text.style.DynamicDrawableSpan;
182import android.text.style.ImageSpan;
183import android.util.AtomicFile;
184import android.util.EventLog;
185import android.util.Log;
186import android.util.Pair;
187import android.util.PrintWriterPrinter;
188import android.util.Slog;
189import android.util.SparseArray;
190import android.util.TimeUtils;
191import android.util.Xml;
192import android.view.Gravity;
193import android.view.LayoutInflater;
194import android.view.View;
195import android.view.WindowManager;
196import android.widget.TextView;
197
198import java.io.BufferedInputStream;
199import java.io.BufferedOutputStream;
200import java.io.DataInputStream;
201import java.io.DataOutputStream;
202import java.io.File;
203import java.io.FileDescriptor;
204import java.io.FileInputStream;
205import java.io.FileNotFoundException;
206import java.io.FileOutputStream;
207import java.io.IOException;
208import java.io.InputStreamReader;
209import java.io.PrintWriter;
210import java.io.StringWriter;
211import java.lang.ref.WeakReference;
212import java.util.ArrayList;
213import java.util.Arrays;
214import java.util.Collections;
215import java.util.Comparator;
216import java.util.HashMap;
217import java.util.HashSet;
218import java.util.Iterator;
219import java.util.List;
220import java.util.Locale;
221import java.util.Map;
222import java.util.Set;
223import java.util.concurrent.atomic.AtomicBoolean;
224import java.util.concurrent.atomic.AtomicLong;
225
226public final class ActivityManagerService extends ActivityManagerNative
227        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
228    private static final String USER_DATA_DIR = "/data/user/";
229    static final String TAG = "ActivityManager";
230    static final String TAG_MU = "ActivityManagerServiceMU";
231    static final boolean DEBUG = false;
232    static final boolean localLOGV = DEBUG;
233    static final boolean DEBUG_BACKUP = localLOGV || false;
234    static final boolean DEBUG_BROADCAST = localLOGV || false;
235    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
236    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_CLEANUP = localLOGV || false;
238    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
239    static final boolean DEBUG_FOCUS = false;
240    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
241    static final boolean DEBUG_MU = localLOGV || false;
242    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
243    static final boolean DEBUG_LRU = localLOGV || false;
244    static final boolean DEBUG_PAUSE = localLOGV || false;
245    static final boolean DEBUG_POWER = localLOGV || false;
246    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
247    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
248    static final boolean DEBUG_PROCESSES = localLOGV || false;
249    static final boolean DEBUG_PROVIDER = localLOGV || false;
250    static final boolean DEBUG_RESULTS = localLOGV || false;
251    static final boolean DEBUG_SERVICE = localLOGV || false;
252    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
253    static final boolean DEBUG_STACK = localLOGV || false;
254    static final boolean DEBUG_SWITCH = localLOGV || false;
255    static final boolean DEBUG_TASKS = localLOGV || false;
256    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
257    static final boolean DEBUG_TRANSITION = localLOGV || false;
258    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
259    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
260    static final boolean DEBUG_VISBILITY = localLOGV || false;
261    static final boolean DEBUG_PSS = localLOGV || false;
262    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
263    static final boolean VALIDATE_TOKENS = false;
264    static final boolean SHOW_ACTIVITY_START_TIME = true;
265
266    // Control over CPU and battery monitoring.
267    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
268    static final boolean MONITOR_CPU_USAGE = true;
269    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
270    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
271    static final boolean MONITOR_THREAD_CPU_USAGE = false;
272
273    // The flags that are set for all calls we make to the package manager.
274    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
275
276    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
277
278    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
279
280    // Maximum number of recent tasks that we can remember.
281    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
282
283    // Amount of time after a call to stopAppSwitches() during which we will
284    // prevent further untrusted switches from happening.
285    static final long APP_SWITCH_DELAY_TIME = 5*1000;
286
287    // How long we wait for a launched process to attach to the activity manager
288    // before we decide it's never going to come up for real.
289    static final int PROC_START_TIMEOUT = 10*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real, when the process was
293    // started with a wrapper for instrumentation (such as Valgrind) because it
294    // could take much longer than usual.
295    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
296
297    // How long to wait after going idle before forcing apps to GC.
298    static final int GC_TIMEOUT = 5*1000;
299
300    // The minimum amount of time between successive GC requests for a process.
301    static final int GC_MIN_INTERVAL = 60*1000;
302
303    // The minimum amount of time between successive PSS requests for a process.
304    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
305
306    // The minimum amount of time between successive PSS requests for a process
307    // when the request is due to the memory state being lowered.
308    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
309
310    // The rate at which we check for apps using excessive power -- 15 mins.
311    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
312
313    // The minimum sample duration we will allow before deciding we have
314    // enough data on wake locks to start killing things.
315    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on CPU usage to start killing things.
319    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // How long we allow a receiver to run before giving up on it.
322    static final int BROADCAST_FG_TIMEOUT = 10*1000;
323    static final int BROADCAST_BG_TIMEOUT = 60*1000;
324
325    // How long we wait until we timeout on key dispatching.
326    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
327
328    // How long we wait until we timeout on key dispatching during instrumentation.
329    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
330
331    // Amount of time we wait for observers to handle a user switch before
332    // giving up on them and unfreezing the screen.
333    static final int USER_SWITCH_TIMEOUT = 2*1000;
334
335    // Maximum number of users we allow to be running at a time.
336    static final int MAX_RUNNING_USERS = 3;
337
338    // How long to wait in getAssistContextExtras for the activity and foreground services
339    // to respond with the result.
340    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
341
342    // Maximum number of persisted Uri grants a package is allowed
343    static final int MAX_PERSISTED_URI_GRANTS = 128;
344
345    static final int MY_PID = Process.myPid();
346
347    static final String[] EMPTY_STRING_ARRAY = new String[0];
348
349    // How many bytes to write into the dropbox log before truncating
350    static final int DROPBOX_MAX_SIZE = 256 * 1024;
351
352    /** All system services */
353    SystemServiceManager mSystemServiceManager;
354
355    /** Run all ActivityStacks through this */
356    ActivityStackSupervisor mStackSupervisor;
357
358    public IntentFirewall mIntentFirewall;
359
360    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
361    // default actuion automatically.  Important for devices without direct input
362    // devices.
363    private boolean mShowDialogs = true;
364
365    /**
366     * Description of a request to start a new activity, which has been held
367     * due to app switches being disabled.
368     */
369    static class PendingActivityLaunch {
370        final ActivityRecord r;
371        final ActivityRecord sourceRecord;
372        final int startFlags;
373        final ActivityStack stack;
374
375        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
376                int _startFlags, ActivityStack _stack) {
377            r = _r;
378            sourceRecord = _sourceRecord;
379            startFlags = _startFlags;
380            stack = _stack;
381        }
382    }
383
384    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
385            = new ArrayList<PendingActivityLaunch>();
386
387    BroadcastQueue mFgBroadcastQueue;
388    BroadcastQueue mBgBroadcastQueue;
389    // Convenient for easy iteration over the queues. Foreground is first
390    // so that dispatch of foreground broadcasts gets precedence.
391    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
392
393    BroadcastQueue broadcastQueueForIntent(Intent intent) {
394        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
395        if (DEBUG_BACKGROUND_BROADCAST) {
396            Slog.i(TAG, "Broadcast intent " + intent + " on "
397                    + (isFg ? "foreground" : "background")
398                    + " queue");
399        }
400        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401    }
402
403    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
404        for (BroadcastQueue queue : mBroadcastQueues) {
405            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
406            if (r != null) {
407                return r;
408            }
409        }
410        return null;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    ArrayList<TaskRecord> mRecentTasks;
422
423    public class PendingAssistExtras extends Binder implements Runnable {
424        public final ActivityRecord activity;
425        public boolean haveResult = false;
426        public Bundle result = null;
427        public PendingAssistExtras(ActivityRecord _activity) {
428            activity = _activity;
429        }
430        @Override
431        public void run() {
432            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
433            synchronized (this) {
434                haveResult = true;
435                notifyAll();
436            }
437        }
438    }
439
440    final ArrayList<PendingAssistExtras> mPendingAssistExtras
441            = new ArrayList<PendingAssistExtras>();
442
443    /**
444     * Process management.
445     */
446    final ProcessList mProcessList = new ProcessList();
447
448    /**
449     * All of the applications we currently have running organized by name.
450     * The keys are strings of the application package name (as
451     * returned by the package manager), and the keys are ApplicationRecord
452     * objects.
453     */
454    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
455
456    /**
457     * Tracking long-term execution of processes to look for abuse and other
458     * bad app behavior.
459     */
460    final ProcessStatsService mProcessStats;
461
462    /**
463     * The currently running isolated processes.
464     */
465    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
466
467    /**
468     * Counter for assigning isolated process uids, to avoid frequently reusing the
469     * same ones.
470     */
471    int mNextIsolatedProcessUid = 0;
472
473    /**
474     * The currently running heavy-weight process, if any.
475     */
476    ProcessRecord mHeavyWeightProcess = null;
477
478    /**
479     * The last time that various processes have crashed.
480     */
481    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
482
483    /**
484     * Information about a process that is currently marked as bad.
485     */
486    static final class BadProcessInfo {
487        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
488            this.time = time;
489            this.shortMsg = shortMsg;
490            this.longMsg = longMsg;
491            this.stack = stack;
492        }
493
494        final long time;
495        final String shortMsg;
496        final String longMsg;
497        final String stack;
498    }
499
500    /**
501     * Set of applications that we consider to be bad, and will reject
502     * incoming broadcasts from (which the user has no control over).
503     * Processes are added to this set when they have crashed twice within
504     * a minimum amount of time; they are removed from it when they are
505     * later restarted (hopefully due to some user action).  The value is the
506     * time it was added to the list.
507     */
508    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
509
510    /**
511     * All of the processes we currently have running organized by pid.
512     * The keys are the pid running the application.
513     *
514     * <p>NOTE: This object is protected by its own lock, NOT the global
515     * activity manager lock!
516     */
517    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
518
519    /**
520     * All of the processes that have been forced to be foreground.  The key
521     * is the pid of the caller who requested it (we hold a death
522     * link on it).
523     */
524    abstract class ForegroundToken implements IBinder.DeathRecipient {
525        int pid;
526        IBinder token;
527    }
528    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
529
530    /**
531     * List of records for processes that someone had tried to start before the
532     * system was ready.  We don't start them at that point, but ensure they
533     * are started by the time booting is complete.
534     */
535    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
536
537    /**
538     * List of persistent applications that are in the process
539     * of being started.
540     */
541    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * Processes that are being forcibly torn down.
545     */
546    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
547
548    /**
549     * List of running applications, sorted by recent usage.
550     * The first entry in the list is the least recently used.
551     */
552    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
553
554    /**
555     * Where in mLruProcesses that the processes hosting activities start.
556     */
557    int mLruProcessActivityStart = 0;
558
559    /**
560     * Where in mLruProcesses that the processes hosting services start.
561     * This is after (lower index) than mLruProcessesActivityStart.
562     */
563    int mLruProcessServiceStart = 0;
564
565    /**
566     * List of processes that should gc as soon as things are idle.
567     */
568    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
569
570    /**
571     * Processes we want to collect PSS data from.
572     */
573    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Last time we requested PSS data of all processes.
577     */
578    long mLastFullPssTime = SystemClock.uptimeMillis();
579
580    /**
581     * If set, the next time we collect PSS data we should do a full collection
582     * with data from native processes and the kernel.
583     */
584    boolean mFullPssPending = false;
585
586    /**
587     * This is the process holding what we currently consider to be
588     * the "home" activity.
589     */
590    ProcessRecord mHomeProcess;
591
592    /**
593     * This is the process holding the activity the user last visited that
594     * is in a different process from the one they are currently in.
595     */
596    ProcessRecord mPreviousProcess;
597
598    /**
599     * The time at which the previous process was last visible.
600     */
601    long mPreviousProcessVisibleTime;
602
603    /**
604     * Which uses have been started, so are allowed to run code.
605     */
606    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
607
608    /**
609     * LRU list of history of current users.  Most recently current is at the end.
610     */
611    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
612
613    /**
614     * Constant array of the users that are currently started.
615     */
616    int[] mStartedUserArray = new int[] { 0 };
617
618    /**
619     * Registered observers of the user switching mechanics.
620     */
621    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
622            = new RemoteCallbackList<IUserSwitchObserver>();
623
624    /**
625     * Currently active user switch.
626     */
627    Object mCurUserSwitchCallback;
628
629    /**
630     * Packages that the user has asked to have run in screen size
631     * compatibility mode instead of filling the screen.
632     */
633    final CompatModePackages mCompatModePackages;
634
635    /**
636     * Set of IntentSenderRecord objects that are currently active.
637     */
638    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
639            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
640
641    /**
642     * Fingerprints (hashCode()) of stack traces that we've
643     * already logged DropBox entries for.  Guarded by itself.  If
644     * something (rogue user app) forces this over
645     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
646     */
647    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
648    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
649
650    /**
651     * Strict Mode background batched logging state.
652     *
653     * The string buffer is guarded by itself, and its lock is also
654     * used to determine if another batched write is already
655     * in-flight.
656     */
657    private final StringBuilder mStrictModeBuffer = new StringBuilder();
658
659    /**
660     * Keeps track of all IIntentReceivers that have been registered for
661     * broadcasts.  Hash keys are the receiver IBinder, hash value is
662     * a ReceiverList.
663     */
664    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
665            new HashMap<IBinder, ReceiverList>();
666
667    /**
668     * Resolver for broadcast intents to registered receivers.
669     * Holds BroadcastFilter (subclass of IntentFilter).
670     */
671    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
672            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
673        @Override
674        protected boolean allowFilterResult(
675                BroadcastFilter filter, List<BroadcastFilter> dest) {
676            IBinder target = filter.receiverList.receiver.asBinder();
677            for (int i=dest.size()-1; i>=0; i--) {
678                if (dest.get(i).receiverList.receiver.asBinder() == target) {
679                    return false;
680                }
681            }
682            return true;
683        }
684
685        @Override
686        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
687            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
688                    || userId == filter.owningUserId) {
689                return super.newResult(filter, match, userId);
690            }
691            return null;
692        }
693
694        @Override
695        protected BroadcastFilter[] newArray(int size) {
696            return new BroadcastFilter[size];
697        }
698
699        @Override
700        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
701            return packageName.equals(filter.packageName);
702        }
703    };
704
705    /**
706     * State of all active sticky broadcasts per user.  Keys are the action of the
707     * sticky Intent, values are an ArrayList of all broadcasted intents with
708     * that action (which should usually be one).  The SparseArray is keyed
709     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
710     * for stickies that are sent to all users.
711     */
712    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
713            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
714
715    final ActiveServices mServices;
716
717    /**
718     * Backup/restore process management
719     */
720    String mBackupAppName = null;
721    BackupRecord mBackupTarget = null;
722
723    final ProviderMap mProviderMap;
724
725    /**
726     * List of content providers who have clients waiting for them.  The
727     * application is currently being launched and the provider will be
728     * removed from this list once it is published.
729     */
730    final ArrayList<ContentProviderRecord> mLaunchingProviders
731            = new ArrayList<ContentProviderRecord>();
732
733    /**
734     * File storing persisted {@link #mGrantedUriPermissions}.
735     */
736    private final AtomicFile mGrantFile;
737
738    /** XML constants used in {@link #mGrantFile} */
739    private static final String TAG_URI_GRANTS = "uri-grants";
740    private static final String TAG_URI_GRANT = "uri-grant";
741    private static final String ATTR_USER_HANDLE = "userHandle";
742    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
743    private static final String ATTR_TARGET_USER_ID = "targetUserId";
744    private static final String ATTR_SOURCE_PKG = "sourcePkg";
745    private static final String ATTR_TARGET_PKG = "targetPkg";
746    private static final String ATTR_URI = "uri";
747    private static final String ATTR_MODE_FLAGS = "modeFlags";
748    private static final String ATTR_CREATED_TIME = "createdTime";
749    private static final String ATTR_PREFIX = "prefix";
750
751    /**
752     * Global set of specific {@link Uri} permissions that have been granted.
753     * This optimized lookup structure maps from {@link UriPermission#targetUid}
754     * to {@link UriPermission#uri} to {@link UriPermission}.
755     */
756    @GuardedBy("this")
757    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
758            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
759
760    public static class GrantUri {
761        public final int sourceUserId;
762        public final Uri uri;
763        public boolean prefix;
764
765        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
766            this.sourceUserId = sourceUserId;
767            this.uri = uri;
768            this.prefix = prefix;
769        }
770
771        @Override
772        public int hashCode() {
773            return toString().hashCode();
774        }
775
776        @Override
777        public boolean equals(Object o) {
778            if (o instanceof GrantUri) {
779                GrantUri other = (GrantUri) o;
780                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
781                        && prefix == other.prefix;
782            }
783            return false;
784        }
785
786        @Override
787        public String toString() {
788            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
789            if (prefix) result += " [prefix]";
790            return result;
791        }
792
793        public String toSafeString() {
794            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
795            if (prefix) result += " [prefix]";
796            return result;
797        }
798
799        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
800            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
801                    ContentProvider.getUriWithoutUserId(uri), false);
802        }
803    }
804
805    CoreSettingsObserver mCoreSettingsObserver;
806
807    /**
808     * Thread-local storage used to carry caller permissions over through
809     * indirect content-provider access.
810     */
811    private class Identity {
812        public int pid;
813        public int uid;
814
815        Identity(int _pid, int _uid) {
816            pid = _pid;
817            uid = _uid;
818        }
819    }
820
821    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
822
823    /**
824     * All information we have collected about the runtime performance of
825     * any user id that can impact battery performance.
826     */
827    final BatteryStatsService mBatteryStatsService;
828
829    /**
830     * Information about component usage
831     */
832    final UsageStatsService mUsageStatsService;
833
834    /**
835     * Information about and control over application operations
836     */
837    final AppOpsService mAppOpsService;
838
839    /**
840     * Save recent tasks information across reboots.
841     */
842    final TaskPersister mTaskPersister;
843
844    /**
845     * Current configuration information.  HistoryRecord objects are given
846     * a reference to this object to indicate which configuration they are
847     * currently running in, so this object must be kept immutable.
848     */
849    Configuration mConfiguration = new Configuration();
850
851    /**
852     * Current sequencing integer of the configuration, for skipping old
853     * configurations.
854     */
855    int mConfigurationSeq = 0;
856
857    /**
858     * Hardware-reported OpenGLES version.
859     */
860    final int GL_ES_VERSION;
861
862    /**
863     * List of initialization arguments to pass to all processes when binding applications to them.
864     * For example, references to the commonly used services.
865     */
866    HashMap<String, IBinder> mAppBindArgs;
867
868    /**
869     * Temporary to avoid allocations.  Protected by main lock.
870     */
871    final StringBuilder mStringBuilder = new StringBuilder(256);
872
873    /**
874     * Used to control how we initialize the service.
875     */
876    ComponentName mTopComponent;
877    String mTopAction = Intent.ACTION_MAIN;
878    String mTopData;
879    boolean mProcessesReady = false;
880    boolean mSystemReady = false;
881    boolean mBooting = false;
882    boolean mWaitingUpdate = false;
883    boolean mDidUpdate = false;
884    boolean mOnBattery = false;
885    boolean mLaunchWarningShown = false;
886
887    Context mContext;
888
889    int mFactoryTest;
890
891    boolean mCheckedForSetup;
892
893    /**
894     * The time at which we will allow normal application switches again,
895     * after a call to {@link #stopAppSwitches()}.
896     */
897    long mAppSwitchesAllowedTime;
898
899    /**
900     * This is set to true after the first switch after mAppSwitchesAllowedTime
901     * is set; any switches after that will clear the time.
902     */
903    boolean mDidAppSwitch;
904
905    /**
906     * Last time (in realtime) at which we checked for power usage.
907     */
908    long mLastPowerCheckRealtime;
909
910    /**
911     * Last time (in uptime) at which we checked for power usage.
912     */
913    long mLastPowerCheckUptime;
914
915    /**
916     * Set while we are wanting to sleep, to prevent any
917     * activities from being started/resumed.
918     */
919    private boolean mSleeping = false;
920
921    /**
922     * Set while we are running a voice interaction.  This overrides
923     * sleeping while it is active.
924     */
925    private boolean mRunningVoice = false;
926
927    /**
928     * State of external calls telling us if the device is asleep.
929     */
930    private boolean mWentToSleep = false;
931
932    /**
933     * State of external call telling us if the lock screen is shown.
934     */
935    private boolean mLockScreenShown = false;
936
937    /**
938     * Set if we are shutting down the system, similar to sleeping.
939     */
940    boolean mShuttingDown = false;
941
942    /**
943     * Current sequence id for oom_adj computation traversal.
944     */
945    int mAdjSeq = 0;
946
947    /**
948     * Current sequence id for process LRU updating.
949     */
950    int mLruSeq = 0;
951
952    /**
953     * Keep track of the non-cached/empty process we last found, to help
954     * determine how to distribute cached/empty processes next time.
955     */
956    int mNumNonCachedProcs = 0;
957
958    /**
959     * Keep track of the number of cached hidden procs, to balance oom adj
960     * distribution between those and empty procs.
961     */
962    int mNumCachedHiddenProcs = 0;
963
964    /**
965     * Keep track of the number of service processes we last found, to
966     * determine on the next iteration which should be B services.
967     */
968    int mNumServiceProcs = 0;
969    int mNewNumAServiceProcs = 0;
970    int mNewNumServiceProcs = 0;
971
972    /**
973     * Allow the current computed overall memory level of the system to go down?
974     * This is set to false when we are killing processes for reasons other than
975     * memory management, so that the now smaller process list will not be taken as
976     * an indication that memory is tighter.
977     */
978    boolean mAllowLowerMemLevel = false;
979
980    /**
981     * The last computed memory level, for holding when we are in a state that
982     * processes are going away for other reasons.
983     */
984    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
985
986    /**
987     * The last total number of process we have, to determine if changes actually look
988     * like a shrinking number of process due to lower RAM.
989     */
990    int mLastNumProcesses;
991
992    /**
993     * The uptime of the last time we performed idle maintenance.
994     */
995    long mLastIdleTime = SystemClock.uptimeMillis();
996
997    /**
998     * Total time spent with RAM that has been added in the past since the last idle time.
999     */
1000    long mLowRamTimeSinceLastIdle = 0;
1001
1002    /**
1003     * If RAM is currently low, when that horrible situation started.
1004     */
1005    long mLowRamStartTime = 0;
1006
1007    /**
1008     * For reporting to battery stats the current top application.
1009     */
1010    private String mCurResumedPackage = null;
1011    private int mCurResumedUid = -1;
1012
1013    /**
1014     * For reporting to battery stats the apps currently running foreground
1015     * service.  The ProcessMap is package/uid tuples; each of these contain
1016     * an array of the currently foreground processes.
1017     */
1018    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1019            = new ProcessMap<ArrayList<ProcessRecord>>();
1020
1021    /**
1022     * This is set if we had to do a delayed dexopt of an app before launching
1023     * it, to increase the ANR timeouts in that case.
1024     */
1025    boolean mDidDexOpt;
1026
1027    /**
1028     * Set if the systemServer made a call to enterSafeMode.
1029     */
1030    boolean mSafeMode;
1031
1032    String mDebugApp = null;
1033    boolean mWaitForDebugger = false;
1034    boolean mDebugTransient = false;
1035    String mOrigDebugApp = null;
1036    boolean mOrigWaitForDebugger = false;
1037    boolean mAlwaysFinishActivities = false;
1038    IActivityController mController = null;
1039    String mProfileApp = null;
1040    ProcessRecord mProfileProc = null;
1041    String mProfileFile;
1042    ParcelFileDescriptor mProfileFd;
1043    int mProfileType = 0;
1044    boolean mAutoStopProfiler = false;
1045    String mOpenGlTraceApp = null;
1046
1047    static class ProcessChangeItem {
1048        static final int CHANGE_ACTIVITIES = 1<<0;
1049        static final int CHANGE_PROCESS_STATE = 1<<1;
1050        int changes;
1051        int uid;
1052        int pid;
1053        int processState;
1054        boolean foregroundActivities;
1055    }
1056
1057    final RemoteCallbackList<IProcessObserver> mProcessObservers
1058            = new RemoteCallbackList<IProcessObserver>();
1059    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1060
1061    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1062            = new ArrayList<ProcessChangeItem>();
1063    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1064            = new ArrayList<ProcessChangeItem>();
1065
1066    /**
1067     * Runtime CPU use collection thread.  This object's lock is used to
1068     * protect all related state.
1069     */
1070    final Thread mProcessCpuThread;
1071
1072    /**
1073     * Used to collect process stats when showing not responding dialog.
1074     * Protected by mProcessCpuThread.
1075     */
1076    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1077            MONITOR_THREAD_CPU_USAGE);
1078    final AtomicLong mLastCpuTime = new AtomicLong(0);
1079    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1080
1081    long mLastWriteTime = 0;
1082
1083    /**
1084     * Used to retain an update lock when the foreground activity is in
1085     * immersive mode.
1086     */
1087    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1088
1089    /**
1090     * Set to true after the system has finished booting.
1091     */
1092    boolean mBooted = false;
1093
1094    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1095    int mProcessLimitOverride = -1;
1096
1097    WindowManagerService mWindowManager;
1098
1099    final ActivityThread mSystemThread;
1100
1101    int mCurrentUserId = 0;
1102    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1103    private UserManagerService mUserManager;
1104
1105    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1106        final ProcessRecord mApp;
1107        final int mPid;
1108        final IApplicationThread mAppThread;
1109
1110        AppDeathRecipient(ProcessRecord app, int pid,
1111                IApplicationThread thread) {
1112            if (localLOGV) Slog.v(
1113                TAG, "New death recipient " + this
1114                + " for thread " + thread.asBinder());
1115            mApp = app;
1116            mPid = pid;
1117            mAppThread = thread;
1118        }
1119
1120        @Override
1121        public void binderDied() {
1122            if (localLOGV) Slog.v(
1123                TAG, "Death received in " + this
1124                + " for thread " + mAppThread.asBinder());
1125            synchronized(ActivityManagerService.this) {
1126                appDiedLocked(mApp, mPid, mAppThread);
1127            }
1128        }
1129    }
1130
1131    static final int SHOW_ERROR_MSG = 1;
1132    static final int SHOW_NOT_RESPONDING_MSG = 2;
1133    static final int SHOW_FACTORY_ERROR_MSG = 3;
1134    static final int UPDATE_CONFIGURATION_MSG = 4;
1135    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1136    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1137    static final int SERVICE_TIMEOUT_MSG = 12;
1138    static final int UPDATE_TIME_ZONE = 13;
1139    static final int SHOW_UID_ERROR_MSG = 14;
1140    static final int IM_FEELING_LUCKY_MSG = 15;
1141    static final int PROC_START_TIMEOUT_MSG = 20;
1142    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1143    static final int KILL_APPLICATION_MSG = 22;
1144    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1145    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1146    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1147    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1148    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1149    static final int CLEAR_DNS_CACHE_MSG = 28;
1150    static final int UPDATE_HTTP_PROXY_MSG = 29;
1151    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1152    static final int DISPATCH_PROCESSES_CHANGED = 31;
1153    static final int DISPATCH_PROCESS_DIED = 32;
1154    static final int REPORT_MEM_USAGE_MSG = 33;
1155    static final int REPORT_USER_SWITCH_MSG = 34;
1156    static final int CONTINUE_USER_SWITCH_MSG = 35;
1157    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1158    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1159    static final int PERSIST_URI_GRANTS_MSG = 38;
1160    static final int REQUEST_ALL_PSS_MSG = 39;
1161    static final int START_PROFILES_MSG = 40;
1162    static final int UPDATE_TIME = 41;
1163    static final int SYSTEM_USER_START_MSG = 42;
1164    static final int SYSTEM_USER_CURRENT_MSG = 43;
1165
1166    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1167    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1168    static final int FIRST_COMPAT_MODE_MSG = 300;
1169    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1170
1171    AlertDialog mUidAlert;
1172    CompatModeDialog mCompatModeDialog;
1173    long mLastMemUsageReportTime = 0;
1174
1175    private LockToAppRequestDialog mLockToAppRequest;
1176
1177    /**
1178     * Flag whether the current user is a "monkey", i.e. whether
1179     * the UI is driven by a UI automation tool.
1180     */
1181    private boolean mUserIsMonkey;
1182
1183    final ServiceThread mHandlerThread;
1184    final MainHandler mHandler;
1185
1186    final class MainHandler extends Handler {
1187        public MainHandler(Looper looper) {
1188            super(looper, null, true);
1189        }
1190
1191        @Override
1192        public void handleMessage(Message msg) {
1193            switch (msg.what) {
1194            case SHOW_ERROR_MSG: {
1195                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1196                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1197                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1198                synchronized (ActivityManagerService.this) {
1199                    ProcessRecord proc = (ProcessRecord)data.get("app");
1200                    AppErrorResult res = (AppErrorResult) data.get("result");
1201                    if (proc != null && proc.crashDialog != null) {
1202                        Slog.e(TAG, "App already has crash dialog: " + proc);
1203                        if (res != null) {
1204                            res.set(0);
1205                        }
1206                        return;
1207                    }
1208                    if (!showBackground && UserHandle.getAppId(proc.uid)
1209                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1210                            && proc.pid != MY_PID) {
1211                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1212                        if (res != null) {
1213                            res.set(0);
1214                        }
1215                        return;
1216                    }
1217                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1218                        Dialog d = new AppErrorDialog(mContext,
1219                                ActivityManagerService.this, res, proc);
1220                        d.show();
1221                        proc.crashDialog = d;
1222                    } else {
1223                        // The device is asleep, so just pretend that the user
1224                        // saw a crash dialog and hit "force quit".
1225                        if (res != null) {
1226                            res.set(0);
1227                        }
1228                    }
1229                }
1230
1231                ensureBootCompleted();
1232            } break;
1233            case SHOW_NOT_RESPONDING_MSG: {
1234                synchronized (ActivityManagerService.this) {
1235                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1236                    ProcessRecord proc = (ProcessRecord)data.get("app");
1237                    if (proc != null && proc.anrDialog != null) {
1238                        Slog.e(TAG, "App already has anr dialog: " + proc);
1239                        return;
1240                    }
1241
1242                    Intent intent = new Intent("android.intent.action.ANR");
1243                    if (!mProcessesReady) {
1244                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1245                                | Intent.FLAG_RECEIVER_FOREGROUND);
1246                    }
1247                    broadcastIntentLocked(null, null, intent,
1248                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1249                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1250
1251                    if (mShowDialogs) {
1252                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1253                                mContext, proc, (ActivityRecord)data.get("activity"),
1254                                msg.arg1 != 0);
1255                        d.show();
1256                        proc.anrDialog = d;
1257                    } else {
1258                        // Just kill the app if there is no dialog to be shown.
1259                        killAppAtUsersRequest(proc, null);
1260                    }
1261                }
1262
1263                ensureBootCompleted();
1264            } break;
1265            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1266                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1267                synchronized (ActivityManagerService.this) {
1268                    ProcessRecord proc = (ProcessRecord) data.get("app");
1269                    if (proc == null) {
1270                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1271                        break;
1272                    }
1273                    if (proc.crashDialog != null) {
1274                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1275                        return;
1276                    }
1277                    AppErrorResult res = (AppErrorResult) data.get("result");
1278                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1279                        Dialog d = new StrictModeViolationDialog(mContext,
1280                                ActivityManagerService.this, res, proc);
1281                        d.show();
1282                        proc.crashDialog = d;
1283                    } else {
1284                        // The device is asleep, so just pretend that the user
1285                        // saw a crash dialog and hit "force quit".
1286                        res.set(0);
1287                    }
1288                }
1289                ensureBootCompleted();
1290            } break;
1291            case SHOW_FACTORY_ERROR_MSG: {
1292                Dialog d = new FactoryErrorDialog(
1293                    mContext, msg.getData().getCharSequence("msg"));
1294                d.show();
1295                ensureBootCompleted();
1296            } break;
1297            case UPDATE_CONFIGURATION_MSG: {
1298                final ContentResolver resolver = mContext.getContentResolver();
1299                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1300            } break;
1301            case GC_BACKGROUND_PROCESSES_MSG: {
1302                synchronized (ActivityManagerService.this) {
1303                    performAppGcsIfAppropriateLocked();
1304                }
1305            } break;
1306            case WAIT_FOR_DEBUGGER_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    ProcessRecord app = (ProcessRecord)msg.obj;
1309                    if (msg.arg1 != 0) {
1310                        if (!app.waitedForDebugger) {
1311                            Dialog d = new AppWaitingForDebuggerDialog(
1312                                    ActivityManagerService.this,
1313                                    mContext, app);
1314                            app.waitDialog = d;
1315                            app.waitedForDebugger = true;
1316                            d.show();
1317                        }
1318                    } else {
1319                        if (app.waitDialog != null) {
1320                            app.waitDialog.dismiss();
1321                            app.waitDialog = null;
1322                        }
1323                    }
1324                }
1325            } break;
1326            case SERVICE_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1332                    return;
1333                }
1334                mServices.serviceTimeout((ProcessRecord)msg.obj);
1335            } break;
1336            case UPDATE_TIME_ZONE: {
1337                synchronized (ActivityManagerService.this) {
1338                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1339                        ProcessRecord r = mLruProcesses.get(i);
1340                        if (r.thread != null) {
1341                            try {
1342                                r.thread.updateTimeZone();
1343                            } catch (RemoteException ex) {
1344                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1345                            }
1346                        }
1347                    }
1348                }
1349            } break;
1350            case CLEAR_DNS_CACHE_MSG: {
1351                synchronized (ActivityManagerService.this) {
1352                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1353                        ProcessRecord r = mLruProcesses.get(i);
1354                        if (r.thread != null) {
1355                            try {
1356                                r.thread.clearDnsCache();
1357                            } catch (RemoteException ex) {
1358                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1359                            }
1360                        }
1361                    }
1362                }
1363            } break;
1364            case UPDATE_HTTP_PROXY_MSG: {
1365                ProxyInfo proxy = (ProxyInfo)msg.obj;
1366                String host = "";
1367                String port = "";
1368                String exclList = "";
1369                Uri pacFileUrl = Uri.EMPTY;
1370                if (proxy != null) {
1371                    host = proxy.getHost();
1372                    port = Integer.toString(proxy.getPort());
1373                    exclList = proxy.getExclusionListAsString();
1374                    pacFileUrl = proxy.getPacFileUrl();
1375                }
1376                synchronized (ActivityManagerService.this) {
1377                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1378                        ProcessRecord r = mLruProcesses.get(i);
1379                        if (r.thread != null) {
1380                            try {
1381                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1382                            } catch (RemoteException ex) {
1383                                Slog.w(TAG, "Failed to update http proxy for: " +
1384                                        r.info.processName);
1385                            }
1386                        }
1387                    }
1388                }
1389            } break;
1390            case SHOW_UID_ERROR_MSG: {
1391                String title = "System UIDs Inconsistent";
1392                String text = "UIDs on the system are inconsistent, you need to wipe your"
1393                        + " data partition or your device will be unstable.";
1394                Log.e(TAG, title + ": " + text);
1395                if (mShowDialogs) {
1396                    // XXX This is a temporary dialog, no need to localize.
1397                    AlertDialog d = new BaseErrorDialog(mContext);
1398                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1399                    d.setCancelable(false);
1400                    d.setTitle(title);
1401                    d.setMessage(text);
1402                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1403                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1404                    mUidAlert = d;
1405                    d.show();
1406                }
1407            } break;
1408            case IM_FEELING_LUCKY_MSG: {
1409                if (mUidAlert != null) {
1410                    mUidAlert.dismiss();
1411                    mUidAlert = null;
1412                }
1413            } break;
1414            case PROC_START_TIMEOUT_MSG: {
1415                if (mDidDexOpt) {
1416                    mDidDexOpt = false;
1417                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1418                    nmsg.obj = msg.obj;
1419                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1420                    return;
1421                }
1422                ProcessRecord app = (ProcessRecord)msg.obj;
1423                synchronized (ActivityManagerService.this) {
1424                    processStartTimedOutLocked(app);
1425                }
1426            } break;
1427            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1428                synchronized (ActivityManagerService.this) {
1429                    doPendingActivityLaunchesLocked(true);
1430                }
1431            } break;
1432            case KILL_APPLICATION_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    int appid = msg.arg1;
1435                    boolean restart = (msg.arg2 == 1);
1436                    Bundle bundle = (Bundle)msg.obj;
1437                    String pkg = bundle.getString("pkg");
1438                    String reason = bundle.getString("reason");
1439                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1440                            false, UserHandle.USER_ALL, reason);
1441                }
1442            } break;
1443            case FINALIZE_PENDING_INTENT_MSG: {
1444                ((PendingIntentRecord)msg.obj).completeFinalize();
1445            } break;
1446            case POST_HEAVY_NOTIFICATION_MSG: {
1447                INotificationManager inm = NotificationManager.getService();
1448                if (inm == null) {
1449                    return;
1450                }
1451
1452                ActivityRecord root = (ActivityRecord)msg.obj;
1453                ProcessRecord process = root.app;
1454                if (process == null) {
1455                    return;
1456                }
1457
1458                try {
1459                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1460                    String text = mContext.getString(R.string.heavy_weight_notification,
1461                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1462                    Notification notification = new Notification();
1463                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1464                    notification.when = 0;
1465                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1466                    notification.tickerText = text;
1467                    notification.defaults = 0; // please be quiet
1468                    notification.sound = null;
1469                    notification.vibrate = null;
1470                    notification.setLatestEventInfo(context, text,
1471                            mContext.getText(R.string.heavy_weight_notification_detail),
1472                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1473                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1474                                    new UserHandle(root.userId)));
1475
1476                    try {
1477                        int[] outId = new int[1];
1478                        inm.enqueueNotificationWithTag("android", "android", null,
1479                                R.string.heavy_weight_notification,
1480                                notification, outId, root.userId);
1481                    } catch (RuntimeException e) {
1482                        Slog.w(ActivityManagerService.TAG,
1483                                "Error showing notification for heavy-weight app", e);
1484                    } catch (RemoteException e) {
1485                    }
1486                } catch (NameNotFoundException e) {
1487                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1488                }
1489            } break;
1490            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1491                INotificationManager inm = NotificationManager.getService();
1492                if (inm == null) {
1493                    return;
1494                }
1495                try {
1496                    inm.cancelNotificationWithTag("android", null,
1497                            R.string.heavy_weight_notification,  msg.arg1);
1498                } catch (RuntimeException e) {
1499                    Slog.w(ActivityManagerService.TAG,
1500                            "Error canceling notification for service", e);
1501                } catch (RemoteException e) {
1502                }
1503            } break;
1504            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1505                synchronized (ActivityManagerService.this) {
1506                    checkExcessivePowerUsageLocked(true);
1507                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1508                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1510                }
1511            } break;
1512            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1513                synchronized (ActivityManagerService.this) {
1514                    ActivityRecord ar = (ActivityRecord)msg.obj;
1515                    if (mCompatModeDialog != null) {
1516                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1517                                ar.info.applicationInfo.packageName)) {
1518                            return;
1519                        }
1520                        mCompatModeDialog.dismiss();
1521                        mCompatModeDialog = null;
1522                    }
1523                    if (ar != null && false) {
1524                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1525                                ar.packageName)) {
1526                            int mode = mCompatModePackages.computeCompatModeLocked(
1527                                    ar.info.applicationInfo);
1528                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1529                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1530                                mCompatModeDialog = new CompatModeDialog(
1531                                        ActivityManagerService.this, mContext,
1532                                        ar.info.applicationInfo);
1533                                mCompatModeDialog.show();
1534                            }
1535                        }
1536                    }
1537                }
1538                break;
1539            }
1540            case DISPATCH_PROCESSES_CHANGED: {
1541                dispatchProcessesChanged();
1542                break;
1543            }
1544            case DISPATCH_PROCESS_DIED: {
1545                final int pid = msg.arg1;
1546                final int uid = msg.arg2;
1547                dispatchProcessDied(pid, uid);
1548                break;
1549            }
1550            case REPORT_MEM_USAGE_MSG: {
1551                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1552                Thread thread = new Thread() {
1553                    @Override public void run() {
1554                        final SparseArray<ProcessMemInfo> infoMap
1555                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1556                        for (int i=0, N=memInfos.size(); i<N; i++) {
1557                            ProcessMemInfo mi = memInfos.get(i);
1558                            infoMap.put(mi.pid, mi);
1559                        }
1560                        updateCpuStatsNow();
1561                        synchronized (mProcessCpuThread) {
1562                            final int N = mProcessCpuTracker.countStats();
1563                            for (int i=0; i<N; i++) {
1564                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1565                                if (st.vsize > 0) {
1566                                    long pss = Debug.getPss(st.pid, null);
1567                                    if (pss > 0) {
1568                                        if (infoMap.indexOfKey(st.pid) < 0) {
1569                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1570                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1571                                            mi.pss = pss;
1572                                            memInfos.add(mi);
1573                                        }
1574                                    }
1575                                }
1576                            }
1577                        }
1578
1579                        long totalPss = 0;
1580                        for (int i=0, N=memInfos.size(); i<N; i++) {
1581                            ProcessMemInfo mi = memInfos.get(i);
1582                            if (mi.pss == 0) {
1583                                mi.pss = Debug.getPss(mi.pid, null);
1584                            }
1585                            totalPss += mi.pss;
1586                        }
1587                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1588                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1589                                if (lhs.oomAdj != rhs.oomAdj) {
1590                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1591                                }
1592                                if (lhs.pss != rhs.pss) {
1593                                    return lhs.pss < rhs.pss ? 1 : -1;
1594                                }
1595                                return 0;
1596                            }
1597                        });
1598
1599                        StringBuilder tag = new StringBuilder(128);
1600                        StringBuilder stack = new StringBuilder(128);
1601                        tag.append("Low on memory -- ");
1602                        appendMemBucket(tag, totalPss, "total", false);
1603                        appendMemBucket(stack, totalPss, "total", true);
1604
1605                        StringBuilder logBuilder = new StringBuilder(1024);
1606                        logBuilder.append("Low on memory:\n");
1607
1608                        boolean firstLine = true;
1609                        int lastOomAdj = Integer.MIN_VALUE;
1610                        for (int i=0, N=memInfos.size(); i<N; i++) {
1611                            ProcessMemInfo mi = memInfos.get(i);
1612
1613                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1614                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1615                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1616                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1617                                if (lastOomAdj != mi.oomAdj) {
1618                                    lastOomAdj = mi.oomAdj;
1619                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1620                                        tag.append(" / ");
1621                                    }
1622                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1623                                        if (firstLine) {
1624                                            stack.append(":");
1625                                            firstLine = false;
1626                                        }
1627                                        stack.append("\n\t at ");
1628                                    } else {
1629                                        stack.append("$");
1630                                    }
1631                                } else {
1632                                    tag.append(" ");
1633                                    stack.append("$");
1634                                }
1635                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1636                                    appendMemBucket(tag, mi.pss, mi.name, false);
1637                                }
1638                                appendMemBucket(stack, mi.pss, mi.name, true);
1639                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1640                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1641                                    stack.append("(");
1642                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1643                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1644                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1645                                            stack.append(":");
1646                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1647                                        }
1648                                    }
1649                                    stack.append(")");
1650                                }
1651                            }
1652
1653                            logBuilder.append("  ");
1654                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1655                            logBuilder.append(' ');
1656                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1657                            logBuilder.append(' ');
1658                            ProcessList.appendRamKb(logBuilder, mi.pss);
1659                            logBuilder.append(" kB: ");
1660                            logBuilder.append(mi.name);
1661                            logBuilder.append(" (");
1662                            logBuilder.append(mi.pid);
1663                            logBuilder.append(") ");
1664                            logBuilder.append(mi.adjType);
1665                            logBuilder.append('\n');
1666                            if (mi.adjReason != null) {
1667                                logBuilder.append("                      ");
1668                                logBuilder.append(mi.adjReason);
1669                                logBuilder.append('\n');
1670                            }
1671                        }
1672
1673                        logBuilder.append("           ");
1674                        ProcessList.appendRamKb(logBuilder, totalPss);
1675                        logBuilder.append(" kB: TOTAL\n");
1676
1677                        long[] infos = new long[Debug.MEMINFO_COUNT];
1678                        Debug.getMemInfo(infos);
1679                        logBuilder.append("  MemInfo: ");
1680                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1685                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1686                            logBuilder.append("  ZRAM: ");
1687                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1688                            logBuilder.append(" kB RAM, ");
1689                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1690                            logBuilder.append(" kB swap total, ");
1691                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1692                            logBuilder.append(" kB swap free\n");
1693                        }
1694                        Slog.i(TAG, logBuilder.toString());
1695
1696                        StringBuilder dropBuilder = new StringBuilder(1024);
1697                        /*
1698                        StringWriter oomSw = new StringWriter();
1699                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1700                        StringWriter catSw = new StringWriter();
1701                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                        String[] emptyArgs = new String[] { };
1703                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1704                        oomPw.flush();
1705                        String oomString = oomSw.toString();
1706                        */
1707                        dropBuilder.append(stack);
1708                        dropBuilder.append('\n');
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append(logBuilder);
1711                        dropBuilder.append('\n');
1712                        /*
1713                        dropBuilder.append(oomString);
1714                        dropBuilder.append('\n');
1715                        */
1716                        StringWriter catSw = new StringWriter();
1717                        synchronized (ActivityManagerService.this) {
1718                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1719                            String[] emptyArgs = new String[] { };
1720                            catPw.println();
1721                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1722                            catPw.println();
1723                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1724                                    false, false, null);
1725                            catPw.println();
1726                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1727                            catPw.flush();
1728                        }
1729                        dropBuilder.append(catSw.toString());
1730                        addErrorToDropBox("lowmem", null, "system_server", null,
1731                                null, tag.toString(), dropBuilder.toString(), null, null);
1732                        //Slog.i(TAG, "Sent to dropbox:");
1733                        //Slog.i(TAG, dropBuilder.toString());
1734                        synchronized (ActivityManagerService.this) {
1735                            long now = SystemClock.uptimeMillis();
1736                            if (mLastMemUsageReportTime < now) {
1737                                mLastMemUsageReportTime = now;
1738                            }
1739                        }
1740                    }
1741                };
1742                thread.start();
1743                break;
1744            }
1745            case REPORT_USER_SWITCH_MSG: {
1746                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1747                break;
1748            }
1749            case CONTINUE_USER_SWITCH_MSG: {
1750                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1751                break;
1752            }
1753            case USER_SWITCH_TIMEOUT_MSG: {
1754                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1755                break;
1756            }
1757            case IMMERSIVE_MODE_LOCK_MSG: {
1758                final boolean nextState = (msg.arg1 != 0);
1759                if (mUpdateLock.isHeld() != nextState) {
1760                    if (DEBUG_IMMERSIVE) {
1761                        final ActivityRecord r = (ActivityRecord) msg.obj;
1762                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1763                    }
1764                    if (nextState) {
1765                        mUpdateLock.acquire();
1766                    } else {
1767                        mUpdateLock.release();
1768                    }
1769                }
1770                break;
1771            }
1772            case PERSIST_URI_GRANTS_MSG: {
1773                writeGrantedUriPermissions();
1774                break;
1775            }
1776            case REQUEST_ALL_PSS_MSG: {
1777                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1778                break;
1779            }
1780            case START_PROFILES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    startProfilesLocked();
1783                }
1784                break;
1785            }
1786            case UPDATE_TIME: {
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799                break;
1800            }
1801            case SYSTEM_USER_START_MSG: {
1802                mSystemServiceManager.startUser(msg.arg1);
1803                break;
1804            }
1805            case SYSTEM_USER_CURRENT_MSG: {
1806                mSystemServiceManager.switchUser(msg.arg1);
1807                break;
1808            }
1809            }
1810        }
1811    };
1812
1813    static final int COLLECT_PSS_BG_MSG = 1;
1814
1815    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1816        @Override
1817        public void handleMessage(Message msg) {
1818            switch (msg.what) {
1819            case COLLECT_PSS_BG_MSG: {
1820                long start = SystemClock.uptimeMillis();
1821                MemInfoReader memInfo = null;
1822                synchronized (ActivityManagerService.this) {
1823                    if (mFullPssPending) {
1824                        mFullPssPending = false;
1825                        memInfo = new MemInfoReader();
1826                    }
1827                }
1828                if (memInfo != null) {
1829                    updateCpuStatsNow();
1830                    long nativeTotalPss = 0;
1831                    synchronized (mProcessCpuThread) {
1832                        final int N = mProcessCpuTracker.countStats();
1833                        for (int j=0; j<N; j++) {
1834                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1835                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1836                                // This is definitely an application process; skip it.
1837                                continue;
1838                            }
1839                            synchronized (mPidsSelfLocked) {
1840                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1841                                    // This is one of our own processes; skip it.
1842                                    continue;
1843                                }
1844                            }
1845                            nativeTotalPss += Debug.getPss(st.pid, null);
1846                        }
1847                    }
1848                    memInfo.readMemInfo();
1849                    synchronized (this) {
1850                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1851                                + (SystemClock.uptimeMillis()-start) + "ms");
1852                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1853                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1854                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1855                                        +memInfo.getSlabSizeKb(),
1856                                nativeTotalPss);
1857                    }
1858                }
1859
1860                int i=0, num=0;
1861                long[] tmp = new long[1];
1862                do {
1863                    ProcessRecord proc;
1864                    int procState;
1865                    int pid;
1866                    synchronized (ActivityManagerService.this) {
1867                        if (i >= mPendingPssProcesses.size()) {
1868                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1869                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1870                            mPendingPssProcesses.clear();
1871                            return;
1872                        }
1873                        proc = mPendingPssProcesses.get(i);
1874                        procState = proc.pssProcState;
1875                        if (proc.thread != null && procState == proc.setProcState) {
1876                            pid = proc.pid;
1877                        } else {
1878                            proc = null;
1879                            pid = 0;
1880                        }
1881                        i++;
1882                    }
1883                    if (proc != null) {
1884                        long pss = Debug.getPss(pid, tmp);
1885                        synchronized (ActivityManagerService.this) {
1886                            if (proc.thread != null && proc.setProcState == procState
1887                                    && proc.pid == pid) {
1888                                num++;
1889                                proc.lastPssTime = SystemClock.uptimeMillis();
1890                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1891                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1892                                        + ": " + pss + " lastPss=" + proc.lastPss
1893                                        + " state=" + ProcessList.makeProcStateString(procState));
1894                                if (proc.initialIdlePss == 0) {
1895                                    proc.initialIdlePss = pss;
1896                                }
1897                                proc.lastPss = pss;
1898                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1899                                    proc.lastCachedPss = pss;
1900                                }
1901                            }
1902                        }
1903                    }
1904                } while (true);
1905            }
1906            }
1907        }
1908    };
1909
1910    /**
1911     * Monitor for package changes and update our internal state.
1912     */
1913    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1914        @Override
1915        public void onPackageRemoved(String packageName, int uid) {
1916            // Remove all tasks with activities in the specified package from the list of recent tasks
1917            synchronized (ActivityManagerService.this) {
1918                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1919                    TaskRecord tr = mRecentTasks.get(i);
1920                    ComponentName cn = tr.intent.getComponent();
1921                    if (cn != null && cn.getPackageName().equals(packageName)) {
1922                        // If the package name matches, remove the task and kill the process
1923                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1924                    }
1925                }
1926            }
1927        }
1928
1929        @Override
1930        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1931            onPackageModified(packageName);
1932            return true;
1933        }
1934
1935        @Override
1936        public void onPackageModified(String packageName) {
1937            final PackageManager pm = mContext.getPackageManager();
1938            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1939                    new ArrayList<Pair<Intent, Integer>>();
1940            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1941            // Copy the list of recent tasks so that we don't hold onto the lock on
1942            // ActivityManagerService for long periods while checking if components exist.
1943            synchronized (ActivityManagerService.this) {
1944                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1945                    TaskRecord tr = mRecentTasks.get(i);
1946                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1947                }
1948            }
1949            // Check the recent tasks and filter out all tasks with components that no longer exist.
1950            Intent tmpI = new Intent();
1951            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1952                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1953                ComponentName cn = p.first.getComponent();
1954                if (cn != null && cn.getPackageName().equals(packageName)) {
1955                    try {
1956                        // Add the task to the list to remove if the component no longer exists
1957                        tmpI.setComponent(cn);
1958                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1959                            tasksToRemove.add(p.second);
1960                        }
1961                    } catch (Exception e) {}
1962                }
1963            }
1964            // Prune all the tasks with removed components from the list of recent tasks
1965            synchronized (ActivityManagerService.this) {
1966                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1967                    // Remove the task but don't kill the process (since other components in that
1968                    // package may still be running and in the background)
1969                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1970                }
1971            }
1972        }
1973
1974        @Override
1975        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1976            // Force stop the specified packages
1977            if (packages != null) {
1978                for (String pkg : packages) {
1979                    synchronized (ActivityManagerService.this) {
1980                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1981                                "finished booting")) {
1982                            return true;
1983                        }
1984                    }
1985                }
1986            }
1987            return false;
1988        }
1989    };
1990
1991    public void setSystemProcess() {
1992        try {
1993            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1994            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1995            ServiceManager.addService("meminfo", new MemBinder(this));
1996            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1997            ServiceManager.addService("dbinfo", new DbBinder(this));
1998            if (MONITOR_CPU_USAGE) {
1999                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2000            }
2001            ServiceManager.addService("permission", new PermissionController(this));
2002
2003            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2004                    "android", STOCK_PM_FLAGS);
2005            mSystemThread.installSystemApplicationInfo(info);
2006
2007            synchronized (this) {
2008                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2009                app.persistent = true;
2010                app.pid = MY_PID;
2011                app.maxAdj = ProcessList.SYSTEM_ADJ;
2012                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2013                mProcessNames.put(app.processName, app.uid, app);
2014                synchronized (mPidsSelfLocked) {
2015                    mPidsSelfLocked.put(app.pid, app);
2016                }
2017                updateLruProcessLocked(app, false, null);
2018                updateOomAdjLocked();
2019            }
2020        } catch (PackageManager.NameNotFoundException e) {
2021            throw new RuntimeException(
2022                    "Unable to find android system package", e);
2023        }
2024    }
2025
2026    public void setWindowManager(WindowManagerService wm) {
2027        mWindowManager = wm;
2028        mStackSupervisor.setWindowManager(wm);
2029    }
2030
2031    public void startObservingNativeCrashes() {
2032        final NativeCrashListener ncl = new NativeCrashListener(this);
2033        ncl.start();
2034    }
2035
2036    public IAppOpsService getAppOpsService() {
2037        return mAppOpsService;
2038    }
2039
2040    static class MemBinder extends Binder {
2041        ActivityManagerService mActivityManagerService;
2042        MemBinder(ActivityManagerService activityManagerService) {
2043            mActivityManagerService = activityManagerService;
2044        }
2045
2046        @Override
2047        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2048            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2049                    != PackageManager.PERMISSION_GRANTED) {
2050                pw.println("Permission Denial: can't dump meminfo from from pid="
2051                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2052                        + " without permission " + android.Manifest.permission.DUMP);
2053                return;
2054            }
2055
2056            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2057        }
2058    }
2059
2060    static class GraphicsBinder extends Binder {
2061        ActivityManagerService mActivityManagerService;
2062        GraphicsBinder(ActivityManagerService activityManagerService) {
2063            mActivityManagerService = activityManagerService;
2064        }
2065
2066        @Override
2067        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2068            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2069                    != PackageManager.PERMISSION_GRANTED) {
2070                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2071                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2072                        + " without permission " + android.Manifest.permission.DUMP);
2073                return;
2074            }
2075
2076            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2077        }
2078    }
2079
2080    static class DbBinder extends Binder {
2081        ActivityManagerService mActivityManagerService;
2082        DbBinder(ActivityManagerService activityManagerService) {
2083            mActivityManagerService = activityManagerService;
2084        }
2085
2086        @Override
2087        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2088            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2089                    != PackageManager.PERMISSION_GRANTED) {
2090                pw.println("Permission Denial: can't dump dbinfo from from pid="
2091                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2092                        + " without permission " + android.Manifest.permission.DUMP);
2093                return;
2094            }
2095
2096            mActivityManagerService.dumpDbInfo(fd, pw, args);
2097        }
2098    }
2099
2100    static class CpuBinder extends Binder {
2101        ActivityManagerService mActivityManagerService;
2102        CpuBinder(ActivityManagerService activityManagerService) {
2103            mActivityManagerService = activityManagerService;
2104        }
2105
2106        @Override
2107        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2108            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2109                    != PackageManager.PERMISSION_GRANTED) {
2110                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2111                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2112                        + " without permission " + android.Manifest.permission.DUMP);
2113                return;
2114            }
2115
2116            synchronized (mActivityManagerService.mProcessCpuThread) {
2117                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2118                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2119                        SystemClock.uptimeMillis()));
2120            }
2121        }
2122    }
2123
2124    public static final class Lifecycle extends SystemService {
2125        private final ActivityManagerService mService;
2126
2127        public Lifecycle(Context context) {
2128            super(context);
2129            mService = new ActivityManagerService(context);
2130        }
2131
2132        @Override
2133        public void onStart() {
2134            mService.start();
2135        }
2136
2137        public ActivityManagerService getService() {
2138            return mService;
2139        }
2140    }
2141
2142    // Note: This method is invoked on the main thread but may need to attach various
2143    // handlers to other threads.  So take care to be explicit about the looper.
2144    public ActivityManagerService(Context systemContext) {
2145        mContext = systemContext;
2146        mFactoryTest = FactoryTest.getMode();
2147        mSystemThread = ActivityThread.currentActivityThread();
2148
2149        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2150
2151        mHandlerThread = new ServiceThread(TAG,
2152                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2153        mHandlerThread.start();
2154        mHandler = new MainHandler(mHandlerThread.getLooper());
2155
2156        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2157                "foreground", BROADCAST_FG_TIMEOUT, false);
2158        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2159                "background", BROADCAST_BG_TIMEOUT, true);
2160        mBroadcastQueues[0] = mFgBroadcastQueue;
2161        mBroadcastQueues[1] = mBgBroadcastQueue;
2162
2163        mServices = new ActiveServices(this);
2164        mProviderMap = new ProviderMap(this);
2165
2166        // TODO: Move creation of battery stats service outside of activity manager service.
2167        File dataDir = Environment.getDataDirectory();
2168        File systemDir = new File(dataDir, "system");
2169        systemDir.mkdirs();
2170        mBatteryStatsService = new BatteryStatsService(new File(
2171                systemDir, "batterystats.bin").toString(), mHandler);
2172        mBatteryStatsService.getActiveStatistics().readLocked();
2173        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2174        mOnBattery = DEBUG_POWER ? true
2175                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2176        mBatteryStatsService.getActiveStatistics().setCallback(this);
2177
2178        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2179
2180        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2181        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2182
2183        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2184
2185        // User 0 is the first and only user that runs at boot.
2186        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2187        mUserLru.add(Integer.valueOf(0));
2188        updateStartedUserArrayLocked();
2189
2190        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2191            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2192
2193        mConfiguration.setToDefaults();
2194        mConfiguration.setLocale(Locale.getDefault());
2195
2196        mConfigurationSeq = mConfiguration.seq = 1;
2197        mProcessCpuTracker.init();
2198
2199        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2200        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2201        mStackSupervisor = new ActivityStackSupervisor(this);
2202        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2203
2204        mProcessCpuThread = new Thread("CpuTracker") {
2205            @Override
2206            public void run() {
2207                while (true) {
2208                    try {
2209                        try {
2210                            synchronized(this) {
2211                                final long now = SystemClock.uptimeMillis();
2212                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2213                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2214                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2215                                //        + ", write delay=" + nextWriteDelay);
2216                                if (nextWriteDelay < nextCpuDelay) {
2217                                    nextCpuDelay = nextWriteDelay;
2218                                }
2219                                if (nextCpuDelay > 0) {
2220                                    mProcessCpuMutexFree.set(true);
2221                                    this.wait(nextCpuDelay);
2222                                }
2223                            }
2224                        } catch (InterruptedException e) {
2225                        }
2226                        updateCpuStatsNow();
2227                    } catch (Exception e) {
2228                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2229                    }
2230                }
2231            }
2232        };
2233
2234        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2235
2236        Watchdog.getInstance().addMonitor(this);
2237        Watchdog.getInstance().addThread(mHandler);
2238    }
2239
2240    public void setSystemServiceManager(SystemServiceManager mgr) {
2241        mSystemServiceManager = mgr;
2242    }
2243
2244    private void start() {
2245        mProcessCpuThread.start();
2246
2247        mBatteryStatsService.publish(mContext);
2248        mUsageStatsService.publish(mContext);
2249        mAppOpsService.publish(mContext);
2250        Slog.d("AppOps", "AppOpsService published");
2251        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2252    }
2253
2254    public void initPowerManagement() {
2255        mStackSupervisor.initPowerManagement();
2256        mBatteryStatsService.initPowerManagement();
2257    }
2258
2259    @Override
2260    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2261            throws RemoteException {
2262        if (code == SYSPROPS_TRANSACTION) {
2263            // We need to tell all apps about the system property change.
2264            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2265            synchronized(this) {
2266                final int NP = mProcessNames.getMap().size();
2267                for (int ip=0; ip<NP; ip++) {
2268                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2269                    final int NA = apps.size();
2270                    for (int ia=0; ia<NA; ia++) {
2271                        ProcessRecord app = apps.valueAt(ia);
2272                        if (app.thread != null) {
2273                            procs.add(app.thread.asBinder());
2274                        }
2275                    }
2276                }
2277            }
2278
2279            int N = procs.size();
2280            for (int i=0; i<N; i++) {
2281                Parcel data2 = Parcel.obtain();
2282                try {
2283                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2284                } catch (RemoteException e) {
2285                }
2286                data2.recycle();
2287            }
2288        }
2289        try {
2290            return super.onTransact(code, data, reply, flags);
2291        } catch (RuntimeException e) {
2292            // The activity manager only throws security exceptions, so let's
2293            // log all others.
2294            if (!(e instanceof SecurityException)) {
2295                Slog.wtf(TAG, "Activity Manager Crash", e);
2296            }
2297            throw e;
2298        }
2299    }
2300
2301    void updateCpuStats() {
2302        final long now = SystemClock.uptimeMillis();
2303        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2304            return;
2305        }
2306        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2307            synchronized (mProcessCpuThread) {
2308                mProcessCpuThread.notify();
2309            }
2310        }
2311    }
2312
2313    void updateCpuStatsNow() {
2314        synchronized (mProcessCpuThread) {
2315            mProcessCpuMutexFree.set(false);
2316            final long now = SystemClock.uptimeMillis();
2317            boolean haveNewCpuStats = false;
2318
2319            if (MONITOR_CPU_USAGE &&
2320                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2321                mLastCpuTime.set(now);
2322                haveNewCpuStats = true;
2323                mProcessCpuTracker.update();
2324                //Slog.i(TAG, mProcessCpu.printCurrentState());
2325                //Slog.i(TAG, "Total CPU usage: "
2326                //        + mProcessCpu.getTotalCpuPercent() + "%");
2327
2328                // Slog the cpu usage if the property is set.
2329                if ("true".equals(SystemProperties.get("events.cpu"))) {
2330                    int user = mProcessCpuTracker.getLastUserTime();
2331                    int system = mProcessCpuTracker.getLastSystemTime();
2332                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2333                    int irq = mProcessCpuTracker.getLastIrqTime();
2334                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2335                    int idle = mProcessCpuTracker.getLastIdleTime();
2336
2337                    int total = user + system + iowait + irq + softIrq + idle;
2338                    if (total == 0) total = 1;
2339
2340                    EventLog.writeEvent(EventLogTags.CPU,
2341                            ((user+system+iowait+irq+softIrq) * 100) / total,
2342                            (user * 100) / total,
2343                            (system * 100) / total,
2344                            (iowait * 100) / total,
2345                            (irq * 100) / total,
2346                            (softIrq * 100) / total);
2347                }
2348            }
2349
2350            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2351            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2352            synchronized(bstats) {
2353                synchronized(mPidsSelfLocked) {
2354                    if (haveNewCpuStats) {
2355                        if (mOnBattery) {
2356                            int perc = bstats.startAddingCpuLocked();
2357                            int totalUTime = 0;
2358                            int totalSTime = 0;
2359                            final int N = mProcessCpuTracker.countStats();
2360                            for (int i=0; i<N; i++) {
2361                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2362                                if (!st.working) {
2363                                    continue;
2364                                }
2365                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2366                                int otherUTime = (st.rel_utime*perc)/100;
2367                                int otherSTime = (st.rel_stime*perc)/100;
2368                                totalUTime += otherUTime;
2369                                totalSTime += otherSTime;
2370                                if (pr != null) {
2371                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2372                                    if (ps == null || !ps.isActive()) {
2373                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2374                                                pr.info.uid, pr.processName);
2375                                    }
2376                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2377                                            st.rel_stime-otherSTime);
2378                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2379                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2380                                } else {
2381                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2382                                    if (ps == null || !ps.isActive()) {
2383                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2384                                                bstats.mapUid(st.uid), st.name);
2385                                    }
2386                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2387                                            st.rel_stime-otherSTime);
2388                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2389                                }
2390                            }
2391                            bstats.finishAddingCpuLocked(perc, totalUTime,
2392                                    totalSTime, cpuSpeedTimes);
2393                        }
2394                    }
2395                }
2396
2397                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2398                    mLastWriteTime = now;
2399                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2400                }
2401            }
2402        }
2403    }
2404
2405    @Override
2406    public void batteryNeedsCpuUpdate() {
2407        updateCpuStatsNow();
2408    }
2409
2410    @Override
2411    public void batteryPowerChanged(boolean onBattery) {
2412        // When plugging in, update the CPU stats first before changing
2413        // the plug state.
2414        updateCpuStatsNow();
2415        synchronized (this) {
2416            synchronized(mPidsSelfLocked) {
2417                mOnBattery = DEBUG_POWER ? true : onBattery;
2418            }
2419        }
2420    }
2421
2422    /**
2423     * Initialize the application bind args. These are passed to each
2424     * process when the bindApplication() IPC is sent to the process. They're
2425     * lazily setup to make sure the services are running when they're asked for.
2426     */
2427    private HashMap<String, IBinder> getCommonServicesLocked() {
2428        if (mAppBindArgs == null) {
2429            mAppBindArgs = new HashMap<String, IBinder>();
2430
2431            // Setup the application init args
2432            mAppBindArgs.put("package", ServiceManager.getService("package"));
2433            mAppBindArgs.put("window", ServiceManager.getService("window"));
2434            mAppBindArgs.put(Context.ALARM_SERVICE,
2435                    ServiceManager.getService(Context.ALARM_SERVICE));
2436        }
2437        return mAppBindArgs;
2438    }
2439
2440    final void setFocusedActivityLocked(ActivityRecord r) {
2441        if (mFocusedActivity != r) {
2442            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2443            mFocusedActivity = r;
2444            if (r.task != null && r.task.voiceInteractor != null) {
2445                startRunningVoiceLocked();
2446            } else {
2447                finishRunningVoiceLocked();
2448            }
2449            mStackSupervisor.setFocusedStack(r);
2450            if (r != null) {
2451                mWindowManager.setFocusedApp(r.appToken, true);
2452            }
2453            applyUpdateLockStateLocked(r);
2454        }
2455    }
2456
2457    final void clearFocusedActivity(ActivityRecord r) {
2458        if (mFocusedActivity == r) {
2459            mFocusedActivity = null;
2460        }
2461    }
2462
2463    @Override
2464    public void setFocusedStack(int stackId) {
2465        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2466        synchronized (ActivityManagerService.this) {
2467            ActivityStack stack = mStackSupervisor.getStack(stackId);
2468            if (stack != null) {
2469                ActivityRecord r = stack.topRunningActivityLocked(null);
2470                if (r != null) {
2471                    setFocusedActivityLocked(r);
2472                }
2473            }
2474        }
2475    }
2476
2477    @Override
2478    public void notifyActivityDrawn(IBinder token) {
2479        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2480        synchronized (this) {
2481            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2482            if (r != null) {
2483                r.task.stack.notifyActivityDrawnLocked(r);
2484            }
2485        }
2486    }
2487
2488    final void applyUpdateLockStateLocked(ActivityRecord r) {
2489        // Modifications to the UpdateLock state are done on our handler, outside
2490        // the activity manager's locks.  The new state is determined based on the
2491        // state *now* of the relevant activity record.  The object is passed to
2492        // the handler solely for logging detail, not to be consulted/modified.
2493        final boolean nextState = r != null && r.immersive;
2494        mHandler.sendMessage(
2495                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2496    }
2497
2498    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2499        Message msg = Message.obtain();
2500        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2501        msg.obj = r.task.askedCompatMode ? null : r;
2502        mHandler.sendMessage(msg);
2503    }
2504
2505    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2506            String what, Object obj, ProcessRecord srcApp) {
2507        app.lastActivityTime = now;
2508
2509        if (app.activities.size() > 0) {
2510            // Don't want to touch dependent processes that are hosting activities.
2511            return index;
2512        }
2513
2514        int lrui = mLruProcesses.lastIndexOf(app);
2515        if (lrui < 0) {
2516            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2517                    + what + " " + obj + " from " + srcApp);
2518            return index;
2519        }
2520
2521        if (lrui >= index) {
2522            // Don't want to cause this to move dependent processes *back* in the
2523            // list as if they were less frequently used.
2524            return index;
2525        }
2526
2527        if (lrui >= mLruProcessActivityStart) {
2528            // Don't want to touch dependent processes that are hosting activities.
2529            return index;
2530        }
2531
2532        mLruProcesses.remove(lrui);
2533        if (index > 0) {
2534            index--;
2535        }
2536        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2537                + " in LRU list: " + app);
2538        mLruProcesses.add(index, app);
2539        return index;
2540    }
2541
2542    final void removeLruProcessLocked(ProcessRecord app) {
2543        int lrui = mLruProcesses.lastIndexOf(app);
2544        if (lrui >= 0) {
2545            if (lrui <= mLruProcessActivityStart) {
2546                mLruProcessActivityStart--;
2547            }
2548            if (lrui <= mLruProcessServiceStart) {
2549                mLruProcessServiceStart--;
2550            }
2551            mLruProcesses.remove(lrui);
2552        }
2553    }
2554
2555    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2556            ProcessRecord client) {
2557        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2558                || app.treatLikeActivity;
2559        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2560        if (!activityChange && hasActivity) {
2561            // The process has activities, so we are only allowing activity-based adjustments
2562            // to move it.  It should be kept in the front of the list with other
2563            // processes that have activities, and we don't want those to change their
2564            // order except due to activity operations.
2565            return;
2566        }
2567
2568        mLruSeq++;
2569        final long now = SystemClock.uptimeMillis();
2570        app.lastActivityTime = now;
2571
2572        // First a quick reject: if the app is already at the position we will
2573        // put it, then there is nothing to do.
2574        if (hasActivity) {
2575            final int N = mLruProcesses.size();
2576            if (N > 0 && mLruProcesses.get(N-1) == app) {
2577                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2578                return;
2579            }
2580        } else {
2581            if (mLruProcessServiceStart > 0
2582                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2583                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2584                return;
2585            }
2586        }
2587
2588        int lrui = mLruProcesses.lastIndexOf(app);
2589
2590        if (app.persistent && lrui >= 0) {
2591            // We don't care about the position of persistent processes, as long as
2592            // they are in the list.
2593            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2594            return;
2595        }
2596
2597        /* In progress: compute new position first, so we can avoid doing work
2598           if the process is not actually going to move.  Not yet working.
2599        int addIndex;
2600        int nextIndex;
2601        boolean inActivity = false, inService = false;
2602        if (hasActivity) {
2603            // Process has activities, put it at the very tipsy-top.
2604            addIndex = mLruProcesses.size();
2605            nextIndex = mLruProcessServiceStart;
2606            inActivity = true;
2607        } else if (hasService) {
2608            // Process has services, put it at the top of the service list.
2609            addIndex = mLruProcessActivityStart;
2610            nextIndex = mLruProcessServiceStart;
2611            inActivity = true;
2612            inService = true;
2613        } else  {
2614            // Process not otherwise of interest, it goes to the top of the non-service area.
2615            addIndex = mLruProcessServiceStart;
2616            if (client != null) {
2617                int clientIndex = mLruProcesses.lastIndexOf(client);
2618                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2619                        + app);
2620                if (clientIndex >= 0 && addIndex > clientIndex) {
2621                    addIndex = clientIndex;
2622                }
2623            }
2624            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2625        }
2626
2627        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2628                + mLruProcessActivityStart + "): " + app);
2629        */
2630
2631        if (lrui >= 0) {
2632            if (lrui < mLruProcessActivityStart) {
2633                mLruProcessActivityStart--;
2634            }
2635            if (lrui < mLruProcessServiceStart) {
2636                mLruProcessServiceStart--;
2637            }
2638            /*
2639            if (addIndex > lrui) {
2640                addIndex--;
2641            }
2642            if (nextIndex > lrui) {
2643                nextIndex--;
2644            }
2645            */
2646            mLruProcesses.remove(lrui);
2647        }
2648
2649        /*
2650        mLruProcesses.add(addIndex, app);
2651        if (inActivity) {
2652            mLruProcessActivityStart++;
2653        }
2654        if (inService) {
2655            mLruProcessActivityStart++;
2656        }
2657        */
2658
2659        int nextIndex;
2660        if (hasActivity) {
2661            final int N = mLruProcesses.size();
2662            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2663                // Process doesn't have activities, but has clients with
2664                // activities...  move it up, but one below the top (the top
2665                // should always have a real activity).
2666                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2667                mLruProcesses.add(N-1, app);
2668                // To keep it from spamming the LRU list (by making a bunch of clients),
2669                // we will push down any other entries owned by the app.
2670                final int uid = app.info.uid;
2671                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2672                    ProcessRecord subProc = mLruProcesses.get(i);
2673                    if (subProc.info.uid == uid) {
2674                        // We want to push this one down the list.  If the process after
2675                        // it is for the same uid, however, don't do so, because we don't
2676                        // want them internally to be re-ordered.
2677                        if (mLruProcesses.get(i-1).info.uid != uid) {
2678                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2679                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2680                            ProcessRecord tmp = mLruProcesses.get(i);
2681                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2682                            mLruProcesses.set(i-1, tmp);
2683                            i--;
2684                        }
2685                    } else {
2686                        // A gap, we can stop here.
2687                        break;
2688                    }
2689                }
2690            } else {
2691                // Process has activities, put it at the very tipsy-top.
2692                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2693                mLruProcesses.add(app);
2694            }
2695            nextIndex = mLruProcessServiceStart;
2696        } else if (hasService) {
2697            // Process has services, put it at the top of the service list.
2698            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2699            mLruProcesses.add(mLruProcessActivityStart, app);
2700            nextIndex = mLruProcessServiceStart;
2701            mLruProcessActivityStart++;
2702        } else  {
2703            // Process not otherwise of interest, it goes to the top of the non-service area.
2704            int index = mLruProcessServiceStart;
2705            if (client != null) {
2706                // If there is a client, don't allow the process to be moved up higher
2707                // in the list than that client.
2708                int clientIndex = mLruProcesses.lastIndexOf(client);
2709                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2710                        + " when updating " + app);
2711                if (clientIndex <= lrui) {
2712                    // Don't allow the client index restriction to push it down farther in the
2713                    // list than it already is.
2714                    clientIndex = lrui;
2715                }
2716                if (clientIndex >= 0 && index > clientIndex) {
2717                    index = clientIndex;
2718                }
2719            }
2720            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2721            mLruProcesses.add(index, app);
2722            nextIndex = index-1;
2723            mLruProcessActivityStart++;
2724            mLruProcessServiceStart++;
2725        }
2726
2727        // If the app is currently using a content provider or service,
2728        // bump those processes as well.
2729        for (int j=app.connections.size()-1; j>=0; j--) {
2730            ConnectionRecord cr = app.connections.valueAt(j);
2731            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2732                    && cr.binding.service.app != null
2733                    && cr.binding.service.app.lruSeq != mLruSeq
2734                    && !cr.binding.service.app.persistent) {
2735                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2736                        "service connection", cr, app);
2737            }
2738        }
2739        for (int j=app.conProviders.size()-1; j>=0; j--) {
2740            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2741            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2742                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2743                        "provider reference", cpr, app);
2744            }
2745        }
2746    }
2747
2748    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2749        if (uid == Process.SYSTEM_UID) {
2750            // The system gets to run in any process.  If there are multiple
2751            // processes with the same uid, just pick the first (this
2752            // should never happen).
2753            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2754            if (procs == null) return null;
2755            final int N = procs.size();
2756            for (int i = 0; i < N; i++) {
2757                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2758            }
2759        }
2760        ProcessRecord proc = mProcessNames.get(processName, uid);
2761        if (false && proc != null && !keepIfLarge
2762                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2763                && proc.lastCachedPss >= 4000) {
2764            // Turn this condition on to cause killing to happen regularly, for testing.
2765            if (proc.baseProcessTracker != null) {
2766                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2767            }
2768            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2769                    + "k from cached");
2770        } else if (proc != null && !keepIfLarge
2771                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2772                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2773            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2774            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2775                if (proc.baseProcessTracker != null) {
2776                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2777                }
2778                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2779                        + "k from cached");
2780            }
2781        }
2782        return proc;
2783    }
2784
2785    void ensurePackageDexOpt(String packageName) {
2786        IPackageManager pm = AppGlobals.getPackageManager();
2787        try {
2788            if (pm.performDexOpt(packageName)) {
2789                mDidDexOpt = true;
2790            }
2791        } catch (RemoteException e) {
2792        }
2793    }
2794
2795    boolean isNextTransitionForward() {
2796        int transit = mWindowManager.getPendingAppTransition();
2797        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2798                || transit == AppTransition.TRANSIT_TASK_OPEN
2799                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2800    }
2801
2802    final ProcessRecord startProcessLocked(String processName,
2803            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2804            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2805            boolean isolated, boolean keepIfLarge) {
2806        ProcessRecord app;
2807        if (!isolated) {
2808            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2809        } else {
2810            // If this is an isolated process, it can't re-use an existing process.
2811            app = null;
2812        }
2813        // We don't have to do anything more if:
2814        // (1) There is an existing application record; and
2815        // (2) The caller doesn't think it is dead, OR there is no thread
2816        //     object attached to it so we know it couldn't have crashed; and
2817        // (3) There is a pid assigned to it, so it is either starting or
2818        //     already running.
2819        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2820                + " app=" + app + " knownToBeDead=" + knownToBeDead
2821                + " thread=" + (app != null ? app.thread : null)
2822                + " pid=" + (app != null ? app.pid : -1));
2823        if (app != null && app.pid > 0) {
2824            if (!knownToBeDead || app.thread == null) {
2825                // We already have the app running, or are waiting for it to
2826                // come up (we have a pid but not yet its thread), so keep it.
2827                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2828                // If this is a new package in the process, add the package to the list
2829                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2830                return app;
2831            }
2832
2833            // An application record is attached to a previous process,
2834            // clean it up now.
2835            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2836            handleAppDiedLocked(app, true, true);
2837        }
2838
2839        String hostingNameStr = hostingName != null
2840                ? hostingName.flattenToShortString() : null;
2841
2842        if (!isolated) {
2843            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2844                // If we are in the background, then check to see if this process
2845                // is bad.  If so, we will just silently fail.
2846                if (mBadProcesses.get(info.processName, info.uid) != null) {
2847                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2848                            + "/" + info.processName);
2849                    return null;
2850                }
2851            } else {
2852                // When the user is explicitly starting a process, then clear its
2853                // crash count so that we won't make it bad until they see at
2854                // least one crash dialog again, and make the process good again
2855                // if it had been bad.
2856                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2857                        + "/" + info.processName);
2858                mProcessCrashTimes.remove(info.processName, info.uid);
2859                if (mBadProcesses.get(info.processName, info.uid) != null) {
2860                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2861                            UserHandle.getUserId(info.uid), info.uid,
2862                            info.processName);
2863                    mBadProcesses.remove(info.processName, info.uid);
2864                    if (app != null) {
2865                        app.bad = false;
2866                    }
2867                }
2868            }
2869        }
2870
2871        if (app == null) {
2872            app = newProcessRecordLocked(info, processName, isolated);
2873            if (app == null) {
2874                Slog.w(TAG, "Failed making new process record for "
2875                        + processName + "/" + info.uid + " isolated=" + isolated);
2876                return null;
2877            }
2878            mProcessNames.put(processName, app.uid, app);
2879            if (isolated) {
2880                mIsolatedProcesses.put(app.uid, app);
2881            }
2882        } else {
2883            // If this is a new package in the process, add the package to the list
2884            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2885        }
2886
2887        // If the system is not ready yet, then hold off on starting this
2888        // process until it is.
2889        if (!mProcessesReady
2890                && !isAllowedWhileBooting(info)
2891                && !allowWhileBooting) {
2892            if (!mProcessesOnHold.contains(app)) {
2893                mProcessesOnHold.add(app);
2894            }
2895            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2896            return app;
2897        }
2898
2899        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2900        return (app.pid != 0) ? app : null;
2901    }
2902
2903    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2904        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2905    }
2906
2907    private final void startProcessLocked(ProcessRecord app,
2908            String hostingType, String hostingNameStr, String abiOverride) {
2909        if (app.pid > 0 && app.pid != MY_PID) {
2910            synchronized (mPidsSelfLocked) {
2911                mPidsSelfLocked.remove(app.pid);
2912                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2913            }
2914            app.setPid(0);
2915        }
2916
2917        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2918                "startProcessLocked removing on hold: " + app);
2919        mProcessesOnHold.remove(app);
2920
2921        updateCpuStats();
2922
2923        try {
2924            int uid = app.uid;
2925
2926            int[] gids = null;
2927            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2928            if (!app.isolated) {
2929                int[] permGids = null;
2930                try {
2931                    final PackageManager pm = mContext.getPackageManager();
2932                    permGids = pm.getPackageGids(app.info.packageName);
2933
2934                    if (Environment.isExternalStorageEmulated()) {
2935                        if (pm.checkPermission(
2936                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2937                                app.info.packageName) == PERMISSION_GRANTED) {
2938                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2939                        } else {
2940                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2941                        }
2942                    }
2943                } catch (PackageManager.NameNotFoundException e) {
2944                    Slog.w(TAG, "Unable to retrieve gids", e);
2945                }
2946
2947                /*
2948                 * Add shared application and profile GIDs so applications can share some
2949                 * resources like shared libraries and access user-wide resources
2950                 */
2951                if (permGids == null) {
2952                    gids = new int[2];
2953                } else {
2954                    gids = new int[permGids.length + 2];
2955                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2956                }
2957                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2958                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2959            }
2960            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2961                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2962                        && mTopComponent != null
2963                        && app.processName.equals(mTopComponent.getPackageName())) {
2964                    uid = 0;
2965                }
2966                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2967                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2968                    uid = 0;
2969                }
2970            }
2971            int debugFlags = 0;
2972            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2973                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2974                // Also turn on CheckJNI for debuggable apps. It's quite
2975                // awkward to turn on otherwise.
2976                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2977            }
2978            // Run the app in safe mode if its manifest requests so or the
2979            // system is booted in safe mode.
2980            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2981                mSafeMode == true) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2986            }
2987            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2988                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2989            }
2990            if ("1".equals(SystemProperties.get("debug.assert"))) {
2991                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2992            }
2993
2994            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2995            if (requiredAbi == null) {
2996                requiredAbi = Build.SUPPORTED_ABIS[0];
2997            }
2998
2999            // Start the process.  It will either succeed and return a result containing
3000            // the PID of the new process, or else throw a RuntimeException.
3001            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3002                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3003                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3004
3005            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
3006            synchronized (bs) {
3007                if (bs.isOnBattery()) {
3008                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
3009                }
3010            }
3011
3012            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3013                    UserHandle.getUserId(uid), startResult.pid, uid,
3014                    app.processName, hostingType,
3015                    hostingNameStr != null ? hostingNameStr : "");
3016
3017            if (app.persistent) {
3018                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3019            }
3020
3021            StringBuilder buf = mStringBuilder;
3022            buf.setLength(0);
3023            buf.append("Start proc ");
3024            buf.append(app.processName);
3025            buf.append(" for ");
3026            buf.append(hostingType);
3027            if (hostingNameStr != null) {
3028                buf.append(" ");
3029                buf.append(hostingNameStr);
3030            }
3031            buf.append(": pid=");
3032            buf.append(startResult.pid);
3033            buf.append(" uid=");
3034            buf.append(uid);
3035            buf.append(" gids={");
3036            if (gids != null) {
3037                for (int gi=0; gi<gids.length; gi++) {
3038                    if (gi != 0) buf.append(", ");
3039                    buf.append(gids[gi]);
3040
3041                }
3042            }
3043            buf.append("}");
3044            if (requiredAbi != null) {
3045                buf.append(" abi=");
3046                buf.append(requiredAbi);
3047            }
3048            Slog.i(TAG, buf.toString());
3049            app.setPid(startResult.pid);
3050            app.usingWrapper = startResult.usingWrapper;
3051            app.removed = false;
3052            synchronized (mPidsSelfLocked) {
3053                this.mPidsSelfLocked.put(startResult.pid, app);
3054                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3055                msg.obj = app;
3056                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3057                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3058            }
3059            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3060                    app.processName, app.info.uid);
3061            if (app.isolated) {
3062                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3063            }
3064        } catch (RuntimeException e) {
3065            // XXX do better error recovery.
3066            app.setPid(0);
3067            Slog.e(TAG, "Failure starting process " + app.processName, e);
3068        }
3069    }
3070
3071    void updateUsageStats(ActivityRecord component, boolean resumed) {
3072        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3073        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3074        if (resumed) {
3075            mUsageStatsService.noteResumeComponent(component.realActivity);
3076            synchronized (stats) {
3077                stats.noteActivityResumedLocked(component.app.uid);
3078            }
3079        } else {
3080            mUsageStatsService.notePauseComponent(component.realActivity);
3081            synchronized (stats) {
3082                stats.noteActivityPausedLocked(component.app.uid);
3083            }
3084        }
3085    }
3086
3087    Intent getHomeIntent() {
3088        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3089        intent.setComponent(mTopComponent);
3090        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3091            intent.addCategory(Intent.CATEGORY_HOME);
3092        }
3093        return intent;
3094    }
3095
3096    boolean startHomeActivityLocked(int userId) {
3097        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3098                && mTopAction == null) {
3099            // We are running in factory test mode, but unable to find
3100            // the factory test app, so just sit around displaying the
3101            // error message and don't try to start anything.
3102            return false;
3103        }
3104        Intent intent = getHomeIntent();
3105        ActivityInfo aInfo =
3106            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3107        if (aInfo != null) {
3108            intent.setComponent(new ComponentName(
3109                    aInfo.applicationInfo.packageName, aInfo.name));
3110            // Don't do this if the home app is currently being
3111            // instrumented.
3112            aInfo = new ActivityInfo(aInfo);
3113            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3114            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3115                    aInfo.applicationInfo.uid, true);
3116            if (app == null || app.instrumentationClass == null) {
3117                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3118                mStackSupervisor.startHomeActivity(intent, aInfo);
3119            }
3120        }
3121
3122        return true;
3123    }
3124
3125    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3126        ActivityInfo ai = null;
3127        ComponentName comp = intent.getComponent();
3128        try {
3129            if (comp != null) {
3130                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3131            } else {
3132                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3133                        intent,
3134                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3135                            flags, userId);
3136
3137                if (info != null) {
3138                    ai = info.activityInfo;
3139                }
3140            }
3141        } catch (RemoteException e) {
3142            // ignore
3143        }
3144
3145        return ai;
3146    }
3147
3148    /**
3149     * Starts the "new version setup screen" if appropriate.
3150     */
3151    void startSetupActivityLocked() {
3152        // Only do this once per boot.
3153        if (mCheckedForSetup) {
3154            return;
3155        }
3156
3157        // We will show this screen if the current one is a different
3158        // version than the last one shown, and we are not running in
3159        // low-level factory test mode.
3160        final ContentResolver resolver = mContext.getContentResolver();
3161        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3162                Settings.Global.getInt(resolver,
3163                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3164            mCheckedForSetup = true;
3165
3166            // See if we should be showing the platform update setup UI.
3167            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3168            List<ResolveInfo> ris = mContext.getPackageManager()
3169                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3170
3171            // We don't allow third party apps to replace this.
3172            ResolveInfo ri = null;
3173            for (int i=0; ris != null && i<ris.size(); i++) {
3174                if ((ris.get(i).activityInfo.applicationInfo.flags
3175                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3176                    ri = ris.get(i);
3177                    break;
3178                }
3179            }
3180
3181            if (ri != null) {
3182                String vers = ri.activityInfo.metaData != null
3183                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3184                        : null;
3185                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3186                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3187                            Intent.METADATA_SETUP_VERSION);
3188                }
3189                String lastVers = Settings.Secure.getString(
3190                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3191                if (vers != null && !vers.equals(lastVers)) {
3192                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3193                    intent.setComponent(new ComponentName(
3194                            ri.activityInfo.packageName, ri.activityInfo.name));
3195                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3196                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3197                }
3198            }
3199        }
3200    }
3201
3202    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3203        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3204    }
3205
3206    void enforceNotIsolatedCaller(String caller) {
3207        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3208            throw new SecurityException("Isolated process not allowed to call " + caller);
3209        }
3210    }
3211
3212    @Override
3213    public int getFrontActivityScreenCompatMode() {
3214        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3215        synchronized (this) {
3216            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3217        }
3218    }
3219
3220    @Override
3221    public void setFrontActivityScreenCompatMode(int mode) {
3222        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3223                "setFrontActivityScreenCompatMode");
3224        synchronized (this) {
3225            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3226        }
3227    }
3228
3229    @Override
3230    public int getPackageScreenCompatMode(String packageName) {
3231        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3232        synchronized (this) {
3233            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3234        }
3235    }
3236
3237    @Override
3238    public void setPackageScreenCompatMode(String packageName, int mode) {
3239        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3240                "setPackageScreenCompatMode");
3241        synchronized (this) {
3242            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3243        }
3244    }
3245
3246    @Override
3247    public boolean getPackageAskScreenCompat(String packageName) {
3248        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3249        synchronized (this) {
3250            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3251        }
3252    }
3253
3254    @Override
3255    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3256        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3257                "setPackageAskScreenCompat");
3258        synchronized (this) {
3259            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3260        }
3261    }
3262
3263    private void dispatchProcessesChanged() {
3264        int N;
3265        synchronized (this) {
3266            N = mPendingProcessChanges.size();
3267            if (mActiveProcessChanges.length < N) {
3268                mActiveProcessChanges = new ProcessChangeItem[N];
3269            }
3270            mPendingProcessChanges.toArray(mActiveProcessChanges);
3271            mAvailProcessChanges.addAll(mPendingProcessChanges);
3272            mPendingProcessChanges.clear();
3273            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3274        }
3275
3276        int i = mProcessObservers.beginBroadcast();
3277        while (i > 0) {
3278            i--;
3279            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3280            if (observer != null) {
3281                try {
3282                    for (int j=0; j<N; j++) {
3283                        ProcessChangeItem item = mActiveProcessChanges[j];
3284                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3285                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3286                                    + item.pid + " uid=" + item.uid + ": "
3287                                    + item.foregroundActivities);
3288                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3289                                    item.foregroundActivities);
3290                        }
3291                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3292                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3293                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3294                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3295                        }
3296                    }
3297                } catch (RemoteException e) {
3298                }
3299            }
3300        }
3301        mProcessObservers.finishBroadcast();
3302    }
3303
3304    private void dispatchProcessDied(int pid, int uid) {
3305        int i = mProcessObservers.beginBroadcast();
3306        while (i > 0) {
3307            i--;
3308            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3309            if (observer != null) {
3310                try {
3311                    observer.onProcessDied(pid, uid);
3312                } catch (RemoteException e) {
3313                }
3314            }
3315        }
3316        mProcessObservers.finishBroadcast();
3317    }
3318
3319    final void doPendingActivityLaunchesLocked(boolean doResume) {
3320        final int N = mPendingActivityLaunches.size();
3321        if (N <= 0) {
3322            return;
3323        }
3324        for (int i=0; i<N; i++) {
3325            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3326            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3327                    doResume && i == (N-1), null);
3328        }
3329        mPendingActivityLaunches.clear();
3330    }
3331
3332    @Override
3333    public final int startActivity(IApplicationThread caller, String callingPackage,
3334            Intent intent, String resolvedType, IBinder resultTo,
3335            String resultWho, int requestCode, int startFlags,
3336            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3337        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3338                resultWho, requestCode,
3339                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3340    }
3341
3342    @Override
3343    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3344            Intent intent, String resolvedType, IBinder resultTo,
3345            String resultWho, int requestCode, int startFlags,
3346            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3347        enforceNotIsolatedCaller("startActivity");
3348        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3349                false, true, "startActivity", null);
3350        // TODO: Switch to user app stacks here.
3351        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3352                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3353                null, null, options, userId, null);
3354    }
3355
3356    @Override
3357    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3358            Intent intent, String resolvedType, IBinder resultTo,
3359            String resultWho, int requestCode, int startFlags, String profileFile,
3360            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3361        enforceNotIsolatedCaller("startActivityAndWait");
3362        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3363                false, true, "startActivityAndWait", null);
3364        WaitResult res = new WaitResult();
3365        // TODO: Switch to user app stacks here.
3366        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3367                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3368                res, null, options, UserHandle.getCallingUserId(), null);
3369        return res;
3370    }
3371
3372    @Override
3373    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3374            Intent intent, String resolvedType, IBinder resultTo,
3375            String resultWho, int requestCode, int startFlags, Configuration config,
3376            Bundle options, int userId) {
3377        enforceNotIsolatedCaller("startActivityWithConfig");
3378        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3379                false, true, "startActivityWithConfig", null);
3380        // TODO: Switch to user app stacks here.
3381        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3382                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3383                null, null, null, config, options, userId, null);
3384        return ret;
3385    }
3386
3387    @Override
3388    public int startActivityIntentSender(IApplicationThread caller,
3389            IntentSender intent, Intent fillInIntent, String resolvedType,
3390            IBinder resultTo, String resultWho, int requestCode,
3391            int flagsMask, int flagsValues, Bundle options) {
3392        enforceNotIsolatedCaller("startActivityIntentSender");
3393        // Refuse possible leaked file descriptors
3394        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3395            throw new IllegalArgumentException("File descriptors passed in Intent");
3396        }
3397
3398        IIntentSender sender = intent.getTarget();
3399        if (!(sender instanceof PendingIntentRecord)) {
3400            throw new IllegalArgumentException("Bad PendingIntent object");
3401        }
3402
3403        PendingIntentRecord pir = (PendingIntentRecord)sender;
3404
3405        synchronized (this) {
3406            // If this is coming from the currently resumed activity, it is
3407            // effectively saying that app switches are allowed at this point.
3408            final ActivityStack stack = getFocusedStack();
3409            if (stack.mResumedActivity != null &&
3410                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3411                mAppSwitchesAllowedTime = 0;
3412            }
3413        }
3414        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3415                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3416        return ret;
3417    }
3418
3419    @Override
3420    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3421            Intent intent, String resolvedType, IVoiceInteractionSession session,
3422            IVoiceInteractor interactor, int startFlags, String profileFile,
3423            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3424        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3425                != PackageManager.PERMISSION_GRANTED) {
3426            String msg = "Permission Denial: startVoiceActivity() from pid="
3427                    + Binder.getCallingPid()
3428                    + ", uid=" + Binder.getCallingUid()
3429                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3430            Slog.w(TAG, msg);
3431            throw new SecurityException(msg);
3432        }
3433        if (session == null || interactor == null) {
3434            throw new NullPointerException("null session or interactor");
3435        }
3436        userId = handleIncomingUser(callingPid, callingUid, userId,
3437                false, true, "startVoiceActivity", null);
3438        // TODO: Switch to user app stacks here.
3439        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3440                resolvedType, session, interactor, null, null, 0, startFlags,
3441                profileFile, profileFd, null, null, options, userId, null);
3442    }
3443
3444    @Override
3445    public boolean startNextMatchingActivity(IBinder callingActivity,
3446            Intent intent, Bundle options) {
3447        // Refuse possible leaked file descriptors
3448        if (intent != null && intent.hasFileDescriptors() == true) {
3449            throw new IllegalArgumentException("File descriptors passed in Intent");
3450        }
3451
3452        synchronized (this) {
3453            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3454            if (r == null) {
3455                ActivityOptions.abort(options);
3456                return false;
3457            }
3458            if (r.app == null || r.app.thread == null) {
3459                // The caller is not running...  d'oh!
3460                ActivityOptions.abort(options);
3461                return false;
3462            }
3463            intent = new Intent(intent);
3464            // The caller is not allowed to change the data.
3465            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3466            // And we are resetting to find the next component...
3467            intent.setComponent(null);
3468
3469            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3470
3471            ActivityInfo aInfo = null;
3472            try {
3473                List<ResolveInfo> resolves =
3474                    AppGlobals.getPackageManager().queryIntentActivities(
3475                            intent, r.resolvedType,
3476                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3477                            UserHandle.getCallingUserId());
3478
3479                // Look for the original activity in the list...
3480                final int N = resolves != null ? resolves.size() : 0;
3481                for (int i=0; i<N; i++) {
3482                    ResolveInfo rInfo = resolves.get(i);
3483                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3484                            && rInfo.activityInfo.name.equals(r.info.name)) {
3485                        // We found the current one...  the next matching is
3486                        // after it.
3487                        i++;
3488                        if (i<N) {
3489                            aInfo = resolves.get(i).activityInfo;
3490                        }
3491                        if (debug) {
3492                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3493                                    + "/" + r.info.name);
3494                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3495                                    + "/" + aInfo.name);
3496                        }
3497                        break;
3498                    }
3499                }
3500            } catch (RemoteException e) {
3501            }
3502
3503            if (aInfo == null) {
3504                // Nobody who is next!
3505                ActivityOptions.abort(options);
3506                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3507                return false;
3508            }
3509
3510            intent.setComponent(new ComponentName(
3511                    aInfo.applicationInfo.packageName, aInfo.name));
3512            intent.setFlags(intent.getFlags()&~(
3513                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3514                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3515                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3516                    Intent.FLAG_ACTIVITY_NEW_TASK));
3517
3518            // Okay now we need to start the new activity, replacing the
3519            // currently running activity.  This is a little tricky because
3520            // we want to start the new one as if the current one is finished,
3521            // but not finish the current one first so that there is no flicker.
3522            // And thus...
3523            final boolean wasFinishing = r.finishing;
3524            r.finishing = true;
3525
3526            // Propagate reply information over to the new activity.
3527            final ActivityRecord resultTo = r.resultTo;
3528            final String resultWho = r.resultWho;
3529            final int requestCode = r.requestCode;
3530            r.resultTo = null;
3531            if (resultTo != null) {
3532                resultTo.removeResultsLocked(r, resultWho, requestCode);
3533            }
3534
3535            final long origId = Binder.clearCallingIdentity();
3536            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3537                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3538                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3539                    options, false, null, null);
3540            Binder.restoreCallingIdentity(origId);
3541
3542            r.finishing = wasFinishing;
3543            if (res != ActivityManager.START_SUCCESS) {
3544                return false;
3545            }
3546            return true;
3547        }
3548    }
3549
3550    final int startActivityInPackage(int uid, String callingPackage,
3551            Intent intent, String resolvedType, IBinder resultTo,
3552            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3553                    IActivityContainer container) {
3554
3555        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3556                false, true, "startActivityInPackage", null);
3557
3558        // TODO: Switch to user app stacks here.
3559        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3560                null, null, resultTo, resultWho, requestCode, startFlags,
3561                null, null, null, null, options, userId, container);
3562        return ret;
3563    }
3564
3565    @Override
3566    public final int startActivities(IApplicationThread caller, String callingPackage,
3567            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3568            int userId) {
3569        enforceNotIsolatedCaller("startActivities");
3570        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3571                false, true, "startActivity", null);
3572        // TODO: Switch to user app stacks here.
3573        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3574                resolvedTypes, resultTo, options, userId);
3575        return ret;
3576    }
3577
3578    final int startActivitiesInPackage(int uid, String callingPackage,
3579            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3580            Bundle options, int userId) {
3581
3582        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3583                false, true, "startActivityInPackage", null);
3584        // TODO: Switch to user app stacks here.
3585        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3586                resultTo, options, userId);
3587        return ret;
3588    }
3589
3590    final void addRecentTaskLocked(TaskRecord task) {
3591        int N = mRecentTasks.size();
3592        // Quick case: check if the top-most recent task is the same.
3593        if (N > 0 && mRecentTasks.get(0) == task) {
3594            return;
3595        }
3596        // Another quick case: never add voice sessions.
3597        if (task.voiceSession != null) {
3598            return;
3599        }
3600        // Remove any existing entries that are the same kind of task.
3601        final Intent intent = task.intent;
3602        final boolean document = intent != null && intent.isDocument();
3603        final ComponentName comp = intent.getComponent();
3604
3605        int maxRecents = task.maxRecents - 1;
3606        for (int i=0; i<N; i++) {
3607            TaskRecord tr = mRecentTasks.get(i);
3608            if (task != tr) {
3609                if (task.userId != tr.userId) {
3610                    continue;
3611                }
3612                final Intent trIntent = tr.intent;
3613                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3614                    (intent == null || !intent.filterEquals(trIntent))) {
3615                    continue;
3616                }
3617                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3618                if (document && trIsDocument) {
3619                    // These are the same document activity (not necessarily the same doc).
3620                    if (maxRecents > 0) {
3621                        --maxRecents;
3622                        continue;
3623                    }
3624                    // Hit the maximum number of documents for this task. Fall through
3625                    // and remove this document from recents.
3626                } else if (document || trIsDocument) {
3627                    // Only one of these is a document. Not the droid we're looking for.
3628                    continue;
3629                }
3630            }
3631
3632            // Either task and tr are the same or, their affinities match or their intents match
3633            // and neither of them is a document, or they are documents using the same activity
3634            // and their maxRecents has been reached.
3635            tr.disposeThumbnail();
3636            mRecentTasks.remove(i);
3637            i--;
3638            N--;
3639            if (task.intent == null) {
3640                // If the new recent task we are adding is not fully
3641                // specified, then replace it with the existing recent task.
3642                task = tr;
3643            }
3644            mTaskPersister.notify(tr, false);
3645        }
3646        if (N >= MAX_RECENT_TASKS) {
3647            mRecentTasks.remove(N-1).disposeThumbnail();
3648        }
3649        mRecentTasks.add(0, task);
3650    }
3651
3652    @Override
3653    public void reportActivityFullyDrawn(IBinder token) {
3654        synchronized (this) {
3655            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3656            if (r == null) {
3657                return;
3658            }
3659            r.reportFullyDrawnLocked();
3660        }
3661    }
3662
3663    @Override
3664    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3665        synchronized (this) {
3666            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3667            if (r == null) {
3668                return;
3669            }
3670            final long origId = Binder.clearCallingIdentity();
3671            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3672            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3673                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3674            if (config != null) {
3675                r.frozenBeforeDestroy = true;
3676                if (!updateConfigurationLocked(config, r, false, false)) {
3677                    mStackSupervisor.resumeTopActivitiesLocked();
3678                }
3679            }
3680            Binder.restoreCallingIdentity(origId);
3681        }
3682    }
3683
3684    @Override
3685    public int getRequestedOrientation(IBinder token) {
3686        synchronized (this) {
3687            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3688            if (r == null) {
3689                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3690            }
3691            return mWindowManager.getAppOrientation(r.appToken);
3692        }
3693    }
3694
3695    /**
3696     * This is the internal entry point for handling Activity.finish().
3697     *
3698     * @param token The Binder token referencing the Activity we want to finish.
3699     * @param resultCode Result code, if any, from this Activity.
3700     * @param resultData Result data (Intent), if any, from this Activity.
3701     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3702     *            the root Activity in the task.
3703     *
3704     * @return Returns true if the activity successfully finished, or false if it is still running.
3705     */
3706    @Override
3707    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3708            boolean finishTask) {
3709        // Refuse possible leaked file descriptors
3710        if (resultData != null && resultData.hasFileDescriptors() == true) {
3711            throw new IllegalArgumentException("File descriptors passed in Intent");
3712        }
3713
3714        synchronized(this) {
3715            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3716            if (r == null) {
3717                return true;
3718            }
3719            // Keep track of the root activity of the task before we finish it
3720            TaskRecord tr = r.task;
3721            ActivityRecord rootR = tr.getRootActivity();
3722            // Do not allow task to finish in Lock Task mode.
3723            if (tr == mStackSupervisor.mLockTaskModeTask) {
3724                if (rootR == r) {
3725                    return false;
3726                }
3727            }
3728            if (mController != null) {
3729                // Find the first activity that is not finishing.
3730                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3731                if (next != null) {
3732                    // ask watcher if this is allowed
3733                    boolean resumeOK = true;
3734                    try {
3735                        resumeOK = mController.activityResuming(next.packageName);
3736                    } catch (RemoteException e) {
3737                        mController = null;
3738                        Watchdog.getInstance().setActivityController(null);
3739                    }
3740
3741                    if (!resumeOK) {
3742                        return false;
3743                    }
3744                }
3745            }
3746            final long origId = Binder.clearCallingIdentity();
3747            try {
3748                boolean res;
3749                if (finishTask && r == rootR) {
3750                    // If requested, remove the task that is associated to this activity only if it
3751                    // was the root activity in the task.  The result code and data is ignored because
3752                    // we don't support returning them across task boundaries.
3753                    res = removeTaskByIdLocked(tr.taskId, 0);
3754                } else {
3755                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3756                            resultData, "app-request", true);
3757                }
3758                return res;
3759            } finally {
3760                Binder.restoreCallingIdentity(origId);
3761            }
3762        }
3763    }
3764
3765    @Override
3766    public final void finishHeavyWeightApp() {
3767        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3768                != PackageManager.PERMISSION_GRANTED) {
3769            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3770                    + Binder.getCallingPid()
3771                    + ", uid=" + Binder.getCallingUid()
3772                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3773            Slog.w(TAG, msg);
3774            throw new SecurityException(msg);
3775        }
3776
3777        synchronized(this) {
3778            if (mHeavyWeightProcess == null) {
3779                return;
3780            }
3781
3782            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3783                    mHeavyWeightProcess.activities);
3784            for (int i=0; i<activities.size(); i++) {
3785                ActivityRecord r = activities.get(i);
3786                if (!r.finishing) {
3787                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3788                            null, "finish-heavy", true);
3789                }
3790            }
3791
3792            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3793                    mHeavyWeightProcess.userId, 0));
3794            mHeavyWeightProcess = null;
3795        }
3796    }
3797
3798    @Override
3799    public void crashApplication(int uid, int initialPid, String packageName,
3800            String message) {
3801        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3802                != PackageManager.PERMISSION_GRANTED) {
3803            String msg = "Permission Denial: crashApplication() from pid="
3804                    + Binder.getCallingPid()
3805                    + ", uid=" + Binder.getCallingUid()
3806                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3807            Slog.w(TAG, msg);
3808            throw new SecurityException(msg);
3809        }
3810
3811        synchronized(this) {
3812            ProcessRecord proc = null;
3813
3814            // Figure out which process to kill.  We don't trust that initialPid
3815            // still has any relation to current pids, so must scan through the
3816            // list.
3817            synchronized (mPidsSelfLocked) {
3818                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3819                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3820                    if (p.uid != uid) {
3821                        continue;
3822                    }
3823                    if (p.pid == initialPid) {
3824                        proc = p;
3825                        break;
3826                    }
3827                    if (p.pkgList.containsKey(packageName)) {
3828                        proc = p;
3829                    }
3830                }
3831            }
3832
3833            if (proc == null) {
3834                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3835                        + " initialPid=" + initialPid
3836                        + " packageName=" + packageName);
3837                return;
3838            }
3839
3840            if (proc.thread != null) {
3841                if (proc.pid == Process.myPid()) {
3842                    Log.w(TAG, "crashApplication: trying to crash self!");
3843                    return;
3844                }
3845                long ident = Binder.clearCallingIdentity();
3846                try {
3847                    proc.thread.scheduleCrash(message);
3848                } catch (RemoteException e) {
3849                }
3850                Binder.restoreCallingIdentity(ident);
3851            }
3852        }
3853    }
3854
3855    @Override
3856    public final void finishSubActivity(IBinder token, String resultWho,
3857            int requestCode) {
3858        synchronized(this) {
3859            final long origId = Binder.clearCallingIdentity();
3860            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3861            if (r != null) {
3862                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3863            }
3864            Binder.restoreCallingIdentity(origId);
3865        }
3866    }
3867
3868    @Override
3869    public boolean finishActivityAffinity(IBinder token) {
3870        synchronized(this) {
3871            final long origId = Binder.clearCallingIdentity();
3872            try {
3873                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3874
3875                ActivityRecord rootR = r.task.getRootActivity();
3876                // Do not allow task to finish in Lock Task mode.
3877                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3878                    if (rootR == r) {
3879                        Binder.restoreCallingIdentity(origId);
3880                        return false;
3881                    }
3882                }
3883                boolean res = false;
3884                if (r != null) {
3885                    res = r.task.stack.finishActivityAffinityLocked(r);
3886                }
3887                return res;
3888            } finally {
3889                Binder.restoreCallingIdentity(origId);
3890            }
3891        }
3892    }
3893
3894    @Override
3895    public boolean willActivityBeVisible(IBinder token) {
3896        synchronized(this) {
3897            ActivityStack stack = ActivityRecord.getStackLocked(token);
3898            if (stack != null) {
3899                return stack.willActivityBeVisibleLocked(token);
3900            }
3901            return false;
3902        }
3903    }
3904
3905    @Override
3906    public void overridePendingTransition(IBinder token, String packageName,
3907            int enterAnim, int exitAnim) {
3908        synchronized(this) {
3909            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3910            if (self == null) {
3911                return;
3912            }
3913
3914            final long origId = Binder.clearCallingIdentity();
3915
3916            if (self.state == ActivityState.RESUMED
3917                    || self.state == ActivityState.PAUSING) {
3918                mWindowManager.overridePendingAppTransition(packageName,
3919                        enterAnim, exitAnim, null);
3920            }
3921
3922            Binder.restoreCallingIdentity(origId);
3923        }
3924    }
3925
3926    /**
3927     * Main function for removing an existing process from the activity manager
3928     * as a result of that process going away.  Clears out all connections
3929     * to the process.
3930     */
3931    private final void handleAppDiedLocked(ProcessRecord app,
3932            boolean restarting, boolean allowRestart) {
3933        int pid = app.pid;
3934        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3935        if (!restarting) {
3936            removeLruProcessLocked(app);
3937            if (pid > 0) {
3938                ProcessList.remove(pid);
3939            }
3940        }
3941
3942        if (mProfileProc == app) {
3943            clearProfilerLocked();
3944        }
3945
3946        // Remove this application's activities from active lists.
3947        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3948
3949        app.activities.clear();
3950
3951        if (app.instrumentationClass != null) {
3952            Slog.w(TAG, "Crash of app " + app.processName
3953                  + " running instrumentation " + app.instrumentationClass);
3954            Bundle info = new Bundle();
3955            info.putString("shortMsg", "Process crashed.");
3956            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3957        }
3958
3959        if (!restarting) {
3960            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3961                // If there was nothing to resume, and we are not already
3962                // restarting this process, but there is a visible activity that
3963                // is hosted by the process...  then make sure all visible
3964                // activities are running, taking care of restarting this
3965                // process.
3966                if (hasVisibleActivities) {
3967                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3968                }
3969            }
3970        }
3971    }
3972
3973    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3974        IBinder threadBinder = thread.asBinder();
3975        // Find the application record.
3976        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3977            ProcessRecord rec = mLruProcesses.get(i);
3978            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3979                return i;
3980            }
3981        }
3982        return -1;
3983    }
3984
3985    final ProcessRecord getRecordForAppLocked(
3986            IApplicationThread thread) {
3987        if (thread == null) {
3988            return null;
3989        }
3990
3991        int appIndex = getLRURecordIndexForAppLocked(thread);
3992        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3993    }
3994
3995    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3996        // If there are no longer any background processes running,
3997        // and the app that died was not running instrumentation,
3998        // then tell everyone we are now low on memory.
3999        boolean haveBg = false;
4000        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4001            ProcessRecord rec = mLruProcesses.get(i);
4002            if (rec.thread != null
4003                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4004                haveBg = true;
4005                break;
4006            }
4007        }
4008
4009        if (!haveBg) {
4010            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4011            if (doReport) {
4012                long now = SystemClock.uptimeMillis();
4013                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4014                    doReport = false;
4015                } else {
4016                    mLastMemUsageReportTime = now;
4017                }
4018            }
4019            final ArrayList<ProcessMemInfo> memInfos
4020                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4021            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4022            long now = SystemClock.uptimeMillis();
4023            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4024                ProcessRecord rec = mLruProcesses.get(i);
4025                if (rec == dyingProc || rec.thread == null) {
4026                    continue;
4027                }
4028                if (doReport) {
4029                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4030                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4031                }
4032                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4033                    // The low memory report is overriding any current
4034                    // state for a GC request.  Make sure to do
4035                    // heavy/important/visible/foreground processes first.
4036                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4037                        rec.lastRequestedGc = 0;
4038                    } else {
4039                        rec.lastRequestedGc = rec.lastLowMemory;
4040                    }
4041                    rec.reportLowMemory = true;
4042                    rec.lastLowMemory = now;
4043                    mProcessesToGc.remove(rec);
4044                    addProcessToGcListLocked(rec);
4045                }
4046            }
4047            if (doReport) {
4048                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4049                mHandler.sendMessage(msg);
4050            }
4051            scheduleAppGcsLocked();
4052        }
4053    }
4054
4055    final void appDiedLocked(ProcessRecord app, int pid,
4056            IApplicationThread thread) {
4057
4058        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4059        synchronized (stats) {
4060            stats.noteProcessDiedLocked(app.info.uid, pid);
4061        }
4062
4063        // Clean up already done if the process has been re-started.
4064        if (app.pid == pid && app.thread != null &&
4065                app.thread.asBinder() == thread.asBinder()) {
4066            boolean doLowMem = app.instrumentationClass == null;
4067            boolean doOomAdj = doLowMem;
4068            if (!app.killedByAm) {
4069                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4070                        + ") has died.");
4071                mAllowLowerMemLevel = true;
4072            } else {
4073                // Note that we always want to do oom adj to update our state with the
4074                // new number of procs.
4075                mAllowLowerMemLevel = false;
4076                doLowMem = false;
4077            }
4078            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4079            if (DEBUG_CLEANUP) Slog.v(
4080                TAG, "Dying app: " + app + ", pid: " + pid
4081                + ", thread: " + thread.asBinder());
4082            handleAppDiedLocked(app, false, true);
4083
4084            if (doOomAdj) {
4085                updateOomAdjLocked();
4086            }
4087            if (doLowMem) {
4088                doLowMemReportIfNeededLocked(app);
4089            }
4090        } else if (app.pid != pid) {
4091            // A new process has already been started.
4092            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4093                    + ") has died and restarted (pid " + app.pid + ").");
4094            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4095        } else if (DEBUG_PROCESSES) {
4096            Slog.d(TAG, "Received spurious death notification for thread "
4097                    + thread.asBinder());
4098        }
4099    }
4100
4101    /**
4102     * If a stack trace dump file is configured, dump process stack traces.
4103     * @param clearTraces causes the dump file to be erased prior to the new
4104     *    traces being written, if true; when false, the new traces will be
4105     *    appended to any existing file content.
4106     * @param firstPids of dalvik VM processes to dump stack traces for first
4107     * @param lastPids of dalvik VM processes to dump stack traces for last
4108     * @param nativeProcs optional list of native process names to dump stack crawls
4109     * @return file containing stack traces, or null if no dump file is configured
4110     */
4111    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4112            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4113        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4114        if (tracesPath == null || tracesPath.length() == 0) {
4115            return null;
4116        }
4117
4118        File tracesFile = new File(tracesPath);
4119        try {
4120            File tracesDir = tracesFile.getParentFile();
4121            if (!tracesDir.exists()) {
4122                tracesFile.mkdirs();
4123                if (!SELinux.restorecon(tracesDir)) {
4124                    return null;
4125                }
4126            }
4127            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4128
4129            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4130            tracesFile.createNewFile();
4131            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4132        } catch (IOException e) {
4133            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4134            return null;
4135        }
4136
4137        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4138        return tracesFile;
4139    }
4140
4141    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4142            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4143        // Use a FileObserver to detect when traces finish writing.
4144        // The order of traces is considered important to maintain for legibility.
4145        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4146            @Override
4147            public synchronized void onEvent(int event, String path) { notify(); }
4148        };
4149
4150        try {
4151            observer.startWatching();
4152
4153            // First collect all of the stacks of the most important pids.
4154            if (firstPids != null) {
4155                try {
4156                    int num = firstPids.size();
4157                    for (int i = 0; i < num; i++) {
4158                        synchronized (observer) {
4159                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4160                            observer.wait(200);  // Wait for write-close, give up after 200msec
4161                        }
4162                    }
4163                } catch (InterruptedException e) {
4164                    Log.wtf(TAG, e);
4165                }
4166            }
4167
4168            // Next collect the stacks of the native pids
4169            if (nativeProcs != null) {
4170                int[] pids = Process.getPidsForCommands(nativeProcs);
4171                if (pids != null) {
4172                    for (int pid : pids) {
4173                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4174                    }
4175                }
4176            }
4177
4178            // Lastly, measure CPU usage.
4179            if (processCpuTracker != null) {
4180                processCpuTracker.init();
4181                System.gc();
4182                processCpuTracker.update();
4183                try {
4184                    synchronized (processCpuTracker) {
4185                        processCpuTracker.wait(500); // measure over 1/2 second.
4186                    }
4187                } catch (InterruptedException e) {
4188                }
4189                processCpuTracker.update();
4190
4191                // We'll take the stack crawls of just the top apps using CPU.
4192                final int N = processCpuTracker.countWorkingStats();
4193                int numProcs = 0;
4194                for (int i=0; i<N && numProcs<5; i++) {
4195                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4196                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4197                        numProcs++;
4198                        try {
4199                            synchronized (observer) {
4200                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4201                                observer.wait(200);  // Wait for write-close, give up after 200msec
4202                            }
4203                        } catch (InterruptedException e) {
4204                            Log.wtf(TAG, e);
4205                        }
4206
4207                    }
4208                }
4209            }
4210        } finally {
4211            observer.stopWatching();
4212        }
4213    }
4214
4215    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4216        if (true || IS_USER_BUILD) {
4217            return;
4218        }
4219        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4220        if (tracesPath == null || tracesPath.length() == 0) {
4221            return;
4222        }
4223
4224        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4225        StrictMode.allowThreadDiskWrites();
4226        try {
4227            final File tracesFile = new File(tracesPath);
4228            final File tracesDir = tracesFile.getParentFile();
4229            final File tracesTmp = new File(tracesDir, "__tmp__");
4230            try {
4231                if (!tracesDir.exists()) {
4232                    tracesFile.mkdirs();
4233                    if (!SELinux.restorecon(tracesDir.getPath())) {
4234                        return;
4235                    }
4236                }
4237                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4238
4239                if (tracesFile.exists()) {
4240                    tracesTmp.delete();
4241                    tracesFile.renameTo(tracesTmp);
4242                }
4243                StringBuilder sb = new StringBuilder();
4244                Time tobj = new Time();
4245                tobj.set(System.currentTimeMillis());
4246                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4247                sb.append(": ");
4248                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4249                sb.append(" since ");
4250                sb.append(msg);
4251                FileOutputStream fos = new FileOutputStream(tracesFile);
4252                fos.write(sb.toString().getBytes());
4253                if (app == null) {
4254                    fos.write("\n*** No application process!".getBytes());
4255                }
4256                fos.close();
4257                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4258            } catch (IOException e) {
4259                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4260                return;
4261            }
4262
4263            if (app != null) {
4264                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4265                firstPids.add(app.pid);
4266                dumpStackTraces(tracesPath, firstPids, null, null, null);
4267            }
4268
4269            File lastTracesFile = null;
4270            File curTracesFile = null;
4271            for (int i=9; i>=0; i--) {
4272                String name = String.format(Locale.US, "slow%02d.txt", i);
4273                curTracesFile = new File(tracesDir, name);
4274                if (curTracesFile.exists()) {
4275                    if (lastTracesFile != null) {
4276                        curTracesFile.renameTo(lastTracesFile);
4277                    } else {
4278                        curTracesFile.delete();
4279                    }
4280                }
4281                lastTracesFile = curTracesFile;
4282            }
4283            tracesFile.renameTo(curTracesFile);
4284            if (tracesTmp.exists()) {
4285                tracesTmp.renameTo(tracesFile);
4286            }
4287        } finally {
4288            StrictMode.setThreadPolicy(oldPolicy);
4289        }
4290    }
4291
4292    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4293            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4294        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4295        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4296
4297        if (mController != null) {
4298            try {
4299                // 0 == continue, -1 = kill process immediately
4300                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4301                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4302            } catch (RemoteException e) {
4303                mController = null;
4304                Watchdog.getInstance().setActivityController(null);
4305            }
4306        }
4307
4308        long anrTime = SystemClock.uptimeMillis();
4309        if (MONITOR_CPU_USAGE) {
4310            updateCpuStatsNow();
4311        }
4312
4313        synchronized (this) {
4314            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4315            if (mShuttingDown) {
4316                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4317                return;
4318            } else if (app.notResponding) {
4319                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4320                return;
4321            } else if (app.crashing) {
4322                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4323                return;
4324            }
4325
4326            // In case we come through here for the same app before completing
4327            // this one, mark as anring now so we will bail out.
4328            app.notResponding = true;
4329
4330            // Log the ANR to the event log.
4331            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4332                    app.processName, app.info.flags, annotation);
4333
4334            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4335            firstPids.add(app.pid);
4336
4337            int parentPid = app.pid;
4338            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4339            if (parentPid != app.pid) firstPids.add(parentPid);
4340
4341            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4342
4343            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4344                ProcessRecord r = mLruProcesses.get(i);
4345                if (r != null && r.thread != null) {
4346                    int pid = r.pid;
4347                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4348                        if (r.persistent) {
4349                            firstPids.add(pid);
4350                        } else {
4351                            lastPids.put(pid, Boolean.TRUE);
4352                        }
4353                    }
4354                }
4355            }
4356        }
4357
4358        // Log the ANR to the main log.
4359        StringBuilder info = new StringBuilder();
4360        info.setLength(0);
4361        info.append("ANR in ").append(app.processName);
4362        if (activity != null && activity.shortComponentName != null) {
4363            info.append(" (").append(activity.shortComponentName).append(")");
4364        }
4365        info.append("\n");
4366        info.append("PID: ").append(app.pid).append("\n");
4367        if (annotation != null) {
4368            info.append("Reason: ").append(annotation).append("\n");
4369        }
4370        if (parent != null && parent != activity) {
4371            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4372        }
4373
4374        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4375
4376        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4377                NATIVE_STACKS_OF_INTEREST);
4378
4379        String cpuInfo = null;
4380        if (MONITOR_CPU_USAGE) {
4381            updateCpuStatsNow();
4382            synchronized (mProcessCpuThread) {
4383                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4384            }
4385            info.append(processCpuTracker.printCurrentLoad());
4386            info.append(cpuInfo);
4387        }
4388
4389        info.append(processCpuTracker.printCurrentState(anrTime));
4390
4391        Slog.e(TAG, info.toString());
4392        if (tracesFile == null) {
4393            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4394            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4395        }
4396
4397        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4398                cpuInfo, tracesFile, null);
4399
4400        if (mController != null) {
4401            try {
4402                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4403                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4404                if (res != 0) {
4405                    if (res < 0 && app.pid != MY_PID) {
4406                        Process.killProcess(app.pid);
4407                    } else {
4408                        synchronized (this) {
4409                            mServices.scheduleServiceTimeoutLocked(app);
4410                        }
4411                    }
4412                    return;
4413                }
4414            } catch (RemoteException e) {
4415                mController = null;
4416                Watchdog.getInstance().setActivityController(null);
4417            }
4418        }
4419
4420        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4421        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4422                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4423
4424        synchronized (this) {
4425            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4426                killUnneededProcessLocked(app, "background ANR");
4427                return;
4428            }
4429
4430            // Set the app's notResponding state, and look up the errorReportReceiver
4431            makeAppNotRespondingLocked(app,
4432                    activity != null ? activity.shortComponentName : null,
4433                    annotation != null ? "ANR " + annotation : "ANR",
4434                    info.toString());
4435
4436            // Bring up the infamous App Not Responding dialog
4437            Message msg = Message.obtain();
4438            HashMap<String, Object> map = new HashMap<String, Object>();
4439            msg.what = SHOW_NOT_RESPONDING_MSG;
4440            msg.obj = map;
4441            msg.arg1 = aboveSystem ? 1 : 0;
4442            map.put("app", app);
4443            if (activity != null) {
4444                map.put("activity", activity);
4445            }
4446
4447            mHandler.sendMessage(msg);
4448        }
4449    }
4450
4451    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4452        if (!mLaunchWarningShown) {
4453            mLaunchWarningShown = true;
4454            mHandler.post(new Runnable() {
4455                @Override
4456                public void run() {
4457                    synchronized (ActivityManagerService.this) {
4458                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4459                        d.show();
4460                        mHandler.postDelayed(new Runnable() {
4461                            @Override
4462                            public void run() {
4463                                synchronized (ActivityManagerService.this) {
4464                                    d.dismiss();
4465                                    mLaunchWarningShown = false;
4466                                }
4467                            }
4468                        }, 4000);
4469                    }
4470                }
4471            });
4472        }
4473    }
4474
4475    @Override
4476    public boolean clearApplicationUserData(final String packageName,
4477            final IPackageDataObserver observer, int userId) {
4478        enforceNotIsolatedCaller("clearApplicationUserData");
4479        int uid = Binder.getCallingUid();
4480        int pid = Binder.getCallingPid();
4481        userId = handleIncomingUser(pid, uid,
4482                userId, false, true, "clearApplicationUserData", null);
4483        long callingId = Binder.clearCallingIdentity();
4484        try {
4485            IPackageManager pm = AppGlobals.getPackageManager();
4486            int pkgUid = -1;
4487            synchronized(this) {
4488                try {
4489                    pkgUid = pm.getPackageUid(packageName, userId);
4490                } catch (RemoteException e) {
4491                }
4492                if (pkgUid == -1) {
4493                    Slog.w(TAG, "Invalid packageName: " + packageName);
4494                    if (observer != null) {
4495                        try {
4496                            observer.onRemoveCompleted(packageName, false);
4497                        } catch (RemoteException e) {
4498                            Slog.i(TAG, "Observer no longer exists.");
4499                        }
4500                    }
4501                    return false;
4502                }
4503                if (uid == pkgUid || checkComponentPermission(
4504                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4505                        pid, uid, -1, true)
4506                        == PackageManager.PERMISSION_GRANTED) {
4507                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4508                } else {
4509                    throw new SecurityException("PID " + pid + " does not have permission "
4510                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4511                                    + " of package " + packageName);
4512                }
4513            }
4514
4515            try {
4516                // Clear application user data
4517                pm.clearApplicationUserData(packageName, observer, userId);
4518
4519                // Remove all permissions granted from/to this package
4520                removeUriPermissionsForPackageLocked(packageName, userId, true);
4521
4522                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4523                        Uri.fromParts("package", packageName, null));
4524                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4525                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4526                        null, null, 0, null, null, null, false, false, userId);
4527            } catch (RemoteException e) {
4528            }
4529        } finally {
4530            Binder.restoreCallingIdentity(callingId);
4531        }
4532        return true;
4533    }
4534
4535    @Override
4536    public void killBackgroundProcesses(final String packageName, int userId) {
4537        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4538                != PackageManager.PERMISSION_GRANTED &&
4539                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4540                        != PackageManager.PERMISSION_GRANTED) {
4541            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4542                    + Binder.getCallingPid()
4543                    + ", uid=" + Binder.getCallingUid()
4544                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4545            Slog.w(TAG, msg);
4546            throw new SecurityException(msg);
4547        }
4548
4549        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4550                userId, true, true, "killBackgroundProcesses", null);
4551        long callingId = Binder.clearCallingIdentity();
4552        try {
4553            IPackageManager pm = AppGlobals.getPackageManager();
4554            synchronized(this) {
4555                int appId = -1;
4556                try {
4557                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4558                } catch (RemoteException e) {
4559                }
4560                if (appId == -1) {
4561                    Slog.w(TAG, "Invalid packageName: " + packageName);
4562                    return;
4563                }
4564                killPackageProcessesLocked(packageName, appId, userId,
4565                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4566            }
4567        } finally {
4568            Binder.restoreCallingIdentity(callingId);
4569        }
4570    }
4571
4572    @Override
4573    public void killAllBackgroundProcesses() {
4574        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4575                != PackageManager.PERMISSION_GRANTED) {
4576            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4577                    + Binder.getCallingPid()
4578                    + ", uid=" + Binder.getCallingUid()
4579                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4580            Slog.w(TAG, msg);
4581            throw new SecurityException(msg);
4582        }
4583
4584        long callingId = Binder.clearCallingIdentity();
4585        try {
4586            synchronized(this) {
4587                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4588                final int NP = mProcessNames.getMap().size();
4589                for (int ip=0; ip<NP; ip++) {
4590                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4591                    final int NA = apps.size();
4592                    for (int ia=0; ia<NA; ia++) {
4593                        ProcessRecord app = apps.valueAt(ia);
4594                        if (app.persistent) {
4595                            // we don't kill persistent processes
4596                            continue;
4597                        }
4598                        if (app.removed) {
4599                            procs.add(app);
4600                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4601                            app.removed = true;
4602                            procs.add(app);
4603                        }
4604                    }
4605                }
4606
4607                int N = procs.size();
4608                for (int i=0; i<N; i++) {
4609                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4610                }
4611                mAllowLowerMemLevel = true;
4612                updateOomAdjLocked();
4613                doLowMemReportIfNeededLocked(null);
4614            }
4615        } finally {
4616            Binder.restoreCallingIdentity(callingId);
4617        }
4618    }
4619
4620    @Override
4621    public void forceStopPackage(final String packageName, int userId) {
4622        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4623                != PackageManager.PERMISSION_GRANTED) {
4624            String msg = "Permission Denial: forceStopPackage() from pid="
4625                    + Binder.getCallingPid()
4626                    + ", uid=" + Binder.getCallingUid()
4627                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4628            Slog.w(TAG, msg);
4629            throw new SecurityException(msg);
4630        }
4631        final int callingPid = Binder.getCallingPid();
4632        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4633                userId, true, true, "forceStopPackage", null);
4634        long callingId = Binder.clearCallingIdentity();
4635        try {
4636            IPackageManager pm = AppGlobals.getPackageManager();
4637            synchronized(this) {
4638                int[] users = userId == UserHandle.USER_ALL
4639                        ? getUsersLocked() : new int[] { userId };
4640                for (int user : users) {
4641                    int pkgUid = -1;
4642                    try {
4643                        pkgUid = pm.getPackageUid(packageName, user);
4644                    } catch (RemoteException e) {
4645                    }
4646                    if (pkgUid == -1) {
4647                        Slog.w(TAG, "Invalid packageName: " + packageName);
4648                        continue;
4649                    }
4650                    try {
4651                        pm.setPackageStoppedState(packageName, true, user);
4652                    } catch (RemoteException e) {
4653                    } catch (IllegalArgumentException e) {
4654                        Slog.w(TAG, "Failed trying to unstop package "
4655                                + packageName + ": " + e);
4656                    }
4657                    if (isUserRunningLocked(user, false)) {
4658                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4659                    }
4660                }
4661            }
4662        } finally {
4663            Binder.restoreCallingIdentity(callingId);
4664        }
4665    }
4666
4667    /*
4668     * The pkg name and app id have to be specified.
4669     */
4670    @Override
4671    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4672        if (pkg == null) {
4673            return;
4674        }
4675        // Make sure the uid is valid.
4676        if (appid < 0) {
4677            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4678            return;
4679        }
4680        int callerUid = Binder.getCallingUid();
4681        // Only the system server can kill an application
4682        if (callerUid == Process.SYSTEM_UID) {
4683            // Post an aysnc message to kill the application
4684            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4685            msg.arg1 = appid;
4686            msg.arg2 = 0;
4687            Bundle bundle = new Bundle();
4688            bundle.putString("pkg", pkg);
4689            bundle.putString("reason", reason);
4690            msg.obj = bundle;
4691            mHandler.sendMessage(msg);
4692        } else {
4693            throw new SecurityException(callerUid + " cannot kill pkg: " +
4694                    pkg);
4695        }
4696    }
4697
4698    @Override
4699    public void closeSystemDialogs(String reason) {
4700        enforceNotIsolatedCaller("closeSystemDialogs");
4701
4702        final int pid = Binder.getCallingPid();
4703        final int uid = Binder.getCallingUid();
4704        final long origId = Binder.clearCallingIdentity();
4705        try {
4706            synchronized (this) {
4707                // Only allow this from foreground processes, so that background
4708                // applications can't abuse it to prevent system UI from being shown.
4709                if (uid >= Process.FIRST_APPLICATION_UID) {
4710                    ProcessRecord proc;
4711                    synchronized (mPidsSelfLocked) {
4712                        proc = mPidsSelfLocked.get(pid);
4713                    }
4714                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4715                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4716                                + " from background process " + proc);
4717                        return;
4718                    }
4719                }
4720                closeSystemDialogsLocked(reason);
4721            }
4722        } finally {
4723            Binder.restoreCallingIdentity(origId);
4724        }
4725    }
4726
4727    void closeSystemDialogsLocked(String reason) {
4728        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4729        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4730                | Intent.FLAG_RECEIVER_FOREGROUND);
4731        if (reason != null) {
4732            intent.putExtra("reason", reason);
4733        }
4734        mWindowManager.closeSystemDialogs(reason);
4735
4736        mStackSupervisor.closeSystemDialogsLocked();
4737
4738        broadcastIntentLocked(null, null, intent, null,
4739                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4740                Process.SYSTEM_UID, UserHandle.USER_ALL);
4741    }
4742
4743    @Override
4744    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4745        enforceNotIsolatedCaller("getProcessMemoryInfo");
4746        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4747        for (int i=pids.length-1; i>=0; i--) {
4748            ProcessRecord proc;
4749            int oomAdj;
4750            synchronized (this) {
4751                synchronized (mPidsSelfLocked) {
4752                    proc = mPidsSelfLocked.get(pids[i]);
4753                    oomAdj = proc != null ? proc.setAdj : 0;
4754                }
4755            }
4756            infos[i] = new Debug.MemoryInfo();
4757            Debug.getMemoryInfo(pids[i], infos[i]);
4758            if (proc != null) {
4759                synchronized (this) {
4760                    if (proc.thread != null && proc.setAdj == oomAdj) {
4761                        // Record this for posterity if the process has been stable.
4762                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4763                                infos[i].getTotalUss(), false, proc.pkgList);
4764                    }
4765                }
4766            }
4767        }
4768        return infos;
4769    }
4770
4771    @Override
4772    public long[] getProcessPss(int[] pids) {
4773        enforceNotIsolatedCaller("getProcessPss");
4774        long[] pss = new long[pids.length];
4775        for (int i=pids.length-1; i>=0; i--) {
4776            ProcessRecord proc;
4777            int oomAdj;
4778            synchronized (this) {
4779                synchronized (mPidsSelfLocked) {
4780                    proc = mPidsSelfLocked.get(pids[i]);
4781                    oomAdj = proc != null ? proc.setAdj : 0;
4782                }
4783            }
4784            long[] tmpUss = new long[1];
4785            pss[i] = Debug.getPss(pids[i], tmpUss);
4786            if (proc != null) {
4787                synchronized (this) {
4788                    if (proc.thread != null && proc.setAdj == oomAdj) {
4789                        // Record this for posterity if the process has been stable.
4790                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4791                    }
4792                }
4793            }
4794        }
4795        return pss;
4796    }
4797
4798    @Override
4799    public void killApplicationProcess(String processName, int uid) {
4800        if (processName == null) {
4801            return;
4802        }
4803
4804        int callerUid = Binder.getCallingUid();
4805        // Only the system server can kill an application
4806        if (callerUid == Process.SYSTEM_UID) {
4807            synchronized (this) {
4808                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4809                if (app != null && app.thread != null) {
4810                    try {
4811                        app.thread.scheduleSuicide();
4812                    } catch (RemoteException e) {
4813                        // If the other end already died, then our work here is done.
4814                    }
4815                } else {
4816                    Slog.w(TAG, "Process/uid not found attempting kill of "
4817                            + processName + " / " + uid);
4818                }
4819            }
4820        } else {
4821            throw new SecurityException(callerUid + " cannot kill app process: " +
4822                    processName);
4823        }
4824    }
4825
4826    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4827        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4828                false, true, false, false, UserHandle.getUserId(uid), reason);
4829        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4830                Uri.fromParts("package", packageName, null));
4831        if (!mProcessesReady) {
4832            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4833                    | Intent.FLAG_RECEIVER_FOREGROUND);
4834        }
4835        intent.putExtra(Intent.EXTRA_UID, uid);
4836        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4837        broadcastIntentLocked(null, null, intent,
4838                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4839                false, false,
4840                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4841    }
4842
4843    private void forceStopUserLocked(int userId, String reason) {
4844        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4845        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4846        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4847                | Intent.FLAG_RECEIVER_FOREGROUND);
4848        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4849        broadcastIntentLocked(null, null, intent,
4850                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4851                false, false,
4852                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4853    }
4854
4855    private final boolean killPackageProcessesLocked(String packageName, int appId,
4856            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4857            boolean doit, boolean evenPersistent, String reason) {
4858        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4859
4860        // Remove all processes this package may have touched: all with the
4861        // same UID (except for the system or root user), and all whose name
4862        // matches the package name.
4863        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4864        final int NP = mProcessNames.getMap().size();
4865        for (int ip=0; ip<NP; ip++) {
4866            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4867            final int NA = apps.size();
4868            for (int ia=0; ia<NA; ia++) {
4869                ProcessRecord app = apps.valueAt(ia);
4870                if (app.persistent && !evenPersistent) {
4871                    // we don't kill persistent processes
4872                    continue;
4873                }
4874                if (app.removed) {
4875                    if (doit) {
4876                        procs.add(app);
4877                    }
4878                    continue;
4879                }
4880
4881                // Skip process if it doesn't meet our oom adj requirement.
4882                if (app.setAdj < minOomAdj) {
4883                    continue;
4884                }
4885
4886                // If no package is specified, we call all processes under the
4887                // give user id.
4888                if (packageName == null) {
4889                    if (app.userId != userId) {
4890                        continue;
4891                    }
4892                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4893                        continue;
4894                    }
4895                // Package has been specified, we want to hit all processes
4896                // that match it.  We need to qualify this by the processes
4897                // that are running under the specified app and user ID.
4898                } else {
4899                    if (UserHandle.getAppId(app.uid) != appId) {
4900                        continue;
4901                    }
4902                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4903                        continue;
4904                    }
4905                    if (!app.pkgList.containsKey(packageName)) {
4906                        continue;
4907                    }
4908                }
4909
4910                // Process has passed all conditions, kill it!
4911                if (!doit) {
4912                    return true;
4913                }
4914                app.removed = true;
4915                procs.add(app);
4916            }
4917        }
4918
4919        int N = procs.size();
4920        for (int i=0; i<N; i++) {
4921            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4922        }
4923        updateOomAdjLocked();
4924        return N > 0;
4925    }
4926
4927    private final boolean forceStopPackageLocked(String name, int appId,
4928            boolean callerWillRestart, boolean purgeCache, boolean doit,
4929            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4930        int i;
4931        int N;
4932
4933        if (userId == UserHandle.USER_ALL && name == null) {
4934            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4935        }
4936
4937        if (appId < 0 && name != null) {
4938            try {
4939                appId = UserHandle.getAppId(
4940                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4941            } catch (RemoteException e) {
4942            }
4943        }
4944
4945        if (doit) {
4946            if (name != null) {
4947                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4948                        + " user=" + userId + ": " + reason);
4949            } else {
4950                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4951            }
4952
4953            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4954            for (int ip=pmap.size()-1; ip>=0; ip--) {
4955                SparseArray<Long> ba = pmap.valueAt(ip);
4956                for (i=ba.size()-1; i>=0; i--) {
4957                    boolean remove = false;
4958                    final int entUid = ba.keyAt(i);
4959                    if (name != null) {
4960                        if (userId == UserHandle.USER_ALL) {
4961                            if (UserHandle.getAppId(entUid) == appId) {
4962                                remove = true;
4963                            }
4964                        } else {
4965                            if (entUid == UserHandle.getUid(userId, appId)) {
4966                                remove = true;
4967                            }
4968                        }
4969                    } else if (UserHandle.getUserId(entUid) == userId) {
4970                        remove = true;
4971                    }
4972                    if (remove) {
4973                        ba.removeAt(i);
4974                    }
4975                }
4976                if (ba.size() == 0) {
4977                    pmap.removeAt(ip);
4978                }
4979            }
4980        }
4981
4982        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4983                -100, callerWillRestart, true, doit, evenPersistent,
4984                name == null ? ("stop user " + userId) : ("stop " + name));
4985
4986        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4987            if (!doit) {
4988                return true;
4989            }
4990            didSomething = true;
4991        }
4992
4993        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4994            if (!doit) {
4995                return true;
4996            }
4997            didSomething = true;
4998        }
4999
5000        if (name == null) {
5001            // Remove all sticky broadcasts from this user.
5002            mStickyBroadcasts.remove(userId);
5003        }
5004
5005        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5006        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5007                userId, providers)) {
5008            if (!doit) {
5009                return true;
5010            }
5011            didSomething = true;
5012        }
5013        N = providers.size();
5014        for (i=0; i<N; i++) {
5015            removeDyingProviderLocked(null, providers.get(i), true);
5016        }
5017
5018        // Remove transient permissions granted from/to this package/user
5019        removeUriPermissionsForPackageLocked(name, userId, false);
5020
5021        if (name == null || uninstalling) {
5022            // Remove pending intents.  For now we only do this when force
5023            // stopping users, because we have some problems when doing this
5024            // for packages -- app widgets are not currently cleaned up for
5025            // such packages, so they can be left with bad pending intents.
5026            if (mIntentSenderRecords.size() > 0) {
5027                Iterator<WeakReference<PendingIntentRecord>> it
5028                        = mIntentSenderRecords.values().iterator();
5029                while (it.hasNext()) {
5030                    WeakReference<PendingIntentRecord> wpir = it.next();
5031                    if (wpir == null) {
5032                        it.remove();
5033                        continue;
5034                    }
5035                    PendingIntentRecord pir = wpir.get();
5036                    if (pir == null) {
5037                        it.remove();
5038                        continue;
5039                    }
5040                    if (name == null) {
5041                        // Stopping user, remove all objects for the user.
5042                        if (pir.key.userId != userId) {
5043                            // Not the same user, skip it.
5044                            continue;
5045                        }
5046                    } else {
5047                        if (UserHandle.getAppId(pir.uid) != appId) {
5048                            // Different app id, skip it.
5049                            continue;
5050                        }
5051                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5052                            // Different user, skip it.
5053                            continue;
5054                        }
5055                        if (!pir.key.packageName.equals(name)) {
5056                            // Different package, skip it.
5057                            continue;
5058                        }
5059                    }
5060                    if (!doit) {
5061                        return true;
5062                    }
5063                    didSomething = true;
5064                    it.remove();
5065                    pir.canceled = true;
5066                    if (pir.key.activity != null) {
5067                        pir.key.activity.pendingResults.remove(pir.ref);
5068                    }
5069                }
5070            }
5071        }
5072
5073        if (doit) {
5074            if (purgeCache && name != null) {
5075                AttributeCache ac = AttributeCache.instance();
5076                if (ac != null) {
5077                    ac.removePackage(name);
5078                }
5079            }
5080            if (mBooted) {
5081                mStackSupervisor.resumeTopActivitiesLocked();
5082                mStackSupervisor.scheduleIdleLocked();
5083            }
5084        }
5085
5086        return didSomething;
5087    }
5088
5089    private final boolean removeProcessLocked(ProcessRecord app,
5090            boolean callerWillRestart, boolean allowRestart, String reason) {
5091        final String name = app.processName;
5092        final int uid = app.uid;
5093        if (DEBUG_PROCESSES) Slog.d(
5094            TAG, "Force removing proc " + app.toShortString() + " (" + name
5095            + "/" + uid + ")");
5096
5097        mProcessNames.remove(name, uid);
5098        mIsolatedProcesses.remove(app.uid);
5099        if (mHeavyWeightProcess == app) {
5100            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5101                    mHeavyWeightProcess.userId, 0));
5102            mHeavyWeightProcess = null;
5103        }
5104        boolean needRestart = false;
5105        if (app.pid > 0 && app.pid != MY_PID) {
5106            int pid = app.pid;
5107            synchronized (mPidsSelfLocked) {
5108                mPidsSelfLocked.remove(pid);
5109                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5110            }
5111            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5112                    app.processName, app.info.uid);
5113            if (app.isolated) {
5114                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5115            }
5116            killUnneededProcessLocked(app, reason);
5117            handleAppDiedLocked(app, true, allowRestart);
5118            removeLruProcessLocked(app);
5119
5120            if (app.persistent && !app.isolated) {
5121                if (!callerWillRestart) {
5122                    addAppLocked(app.info, false, null /* ABI override */);
5123                } else {
5124                    needRestart = true;
5125                }
5126            }
5127        } else {
5128            mRemovedProcesses.add(app);
5129        }
5130
5131        return needRestart;
5132    }
5133
5134    private final void processStartTimedOutLocked(ProcessRecord app) {
5135        final int pid = app.pid;
5136        boolean gone = false;
5137        synchronized (mPidsSelfLocked) {
5138            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5139            if (knownApp != null && knownApp.thread == null) {
5140                mPidsSelfLocked.remove(pid);
5141                gone = true;
5142            }
5143        }
5144
5145        if (gone) {
5146            Slog.w(TAG, "Process " + app + " failed to attach");
5147            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5148                    pid, app.uid, app.processName);
5149            mProcessNames.remove(app.processName, app.uid);
5150            mIsolatedProcesses.remove(app.uid);
5151            if (mHeavyWeightProcess == app) {
5152                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5153                        mHeavyWeightProcess.userId, 0));
5154                mHeavyWeightProcess = null;
5155            }
5156            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5157                    app.processName, app.info.uid);
5158            if (app.isolated) {
5159                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5160            }
5161            // Take care of any launching providers waiting for this process.
5162            checkAppInLaunchingProvidersLocked(app, true);
5163            // Take care of any services that are waiting for the process.
5164            mServices.processStartTimedOutLocked(app);
5165            killUnneededProcessLocked(app, "start timeout");
5166            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5167                Slog.w(TAG, "Unattached app died before backup, skipping");
5168                try {
5169                    IBackupManager bm = IBackupManager.Stub.asInterface(
5170                            ServiceManager.getService(Context.BACKUP_SERVICE));
5171                    bm.agentDisconnected(app.info.packageName);
5172                } catch (RemoteException e) {
5173                    // Can't happen; the backup manager is local
5174                }
5175            }
5176            if (isPendingBroadcastProcessLocked(pid)) {
5177                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5178                skipPendingBroadcastLocked(pid);
5179            }
5180        } else {
5181            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5182        }
5183    }
5184
5185    private final boolean attachApplicationLocked(IApplicationThread thread,
5186            int pid) {
5187
5188        // Find the application record that is being attached...  either via
5189        // the pid if we are running in multiple processes, or just pull the
5190        // next app record if we are emulating process with anonymous threads.
5191        ProcessRecord app;
5192        if (pid != MY_PID && pid >= 0) {
5193            synchronized (mPidsSelfLocked) {
5194                app = mPidsSelfLocked.get(pid);
5195            }
5196        } else {
5197            app = null;
5198        }
5199
5200        if (app == null) {
5201            Slog.w(TAG, "No pending application record for pid " + pid
5202                    + " (IApplicationThread " + thread + "); dropping process");
5203            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5204            if (pid > 0 && pid != MY_PID) {
5205                Process.killProcessQuiet(pid);
5206            } else {
5207                try {
5208                    thread.scheduleExit();
5209                } catch (Exception e) {
5210                    // Ignore exceptions.
5211                }
5212            }
5213            return false;
5214        }
5215
5216        // If this application record is still attached to a previous
5217        // process, clean it up now.
5218        if (app.thread != null) {
5219            handleAppDiedLocked(app, true, true);
5220        }
5221
5222        // Tell the process all about itself.
5223
5224        if (localLOGV) Slog.v(
5225                TAG, "Binding process pid " + pid + " to record " + app);
5226
5227        final String processName = app.processName;
5228        try {
5229            AppDeathRecipient adr = new AppDeathRecipient(
5230                    app, pid, thread);
5231            thread.asBinder().linkToDeath(adr, 0);
5232            app.deathRecipient = adr;
5233        } catch (RemoteException e) {
5234            app.resetPackageList(mProcessStats);
5235            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5236            return false;
5237        }
5238
5239        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5240
5241        app.makeActive(thread, mProcessStats);
5242        app.curAdj = app.setAdj = -100;
5243        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5244        app.forcingToForeground = null;
5245        updateProcessForegroundLocked(app, false, false);
5246        app.hasShownUi = false;
5247        app.debugging = false;
5248        app.cached = false;
5249
5250        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5251
5252        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5253        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5254
5255        if (!normalMode) {
5256            Slog.i(TAG, "Launching preboot mode app: " + app);
5257        }
5258
5259        if (localLOGV) Slog.v(
5260            TAG, "New app record " + app
5261            + " thread=" + thread.asBinder() + " pid=" + pid);
5262        try {
5263            int testMode = IApplicationThread.DEBUG_OFF;
5264            if (mDebugApp != null && mDebugApp.equals(processName)) {
5265                testMode = mWaitForDebugger
5266                    ? IApplicationThread.DEBUG_WAIT
5267                    : IApplicationThread.DEBUG_ON;
5268                app.debugging = true;
5269                if (mDebugTransient) {
5270                    mDebugApp = mOrigDebugApp;
5271                    mWaitForDebugger = mOrigWaitForDebugger;
5272                }
5273            }
5274            String profileFile = app.instrumentationProfileFile;
5275            ParcelFileDescriptor profileFd = null;
5276            boolean profileAutoStop = false;
5277            if (mProfileApp != null && mProfileApp.equals(processName)) {
5278                mProfileProc = app;
5279                profileFile = mProfileFile;
5280                profileFd = mProfileFd;
5281                profileAutoStop = mAutoStopProfiler;
5282            }
5283            boolean enableOpenGlTrace = false;
5284            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5285                enableOpenGlTrace = true;
5286                mOpenGlTraceApp = null;
5287            }
5288
5289            // If the app is being launched for restore or full backup, set it up specially
5290            boolean isRestrictedBackupMode = false;
5291            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5292                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5293                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5294                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5295            }
5296
5297            ensurePackageDexOpt(app.instrumentationInfo != null
5298                    ? app.instrumentationInfo.packageName
5299                    : app.info.packageName);
5300            if (app.instrumentationClass != null) {
5301                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5302            }
5303            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5304                    + processName + " with config " + mConfiguration);
5305            ApplicationInfo appInfo = app.instrumentationInfo != null
5306                    ? app.instrumentationInfo : app.info;
5307            app.compat = compatibilityInfoForPackageLocked(appInfo);
5308            if (profileFd != null) {
5309                profileFd = profileFd.dup();
5310            }
5311            thread.bindApplication(processName, appInfo, providers,
5312                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5313                    app.instrumentationArguments, app.instrumentationWatcher,
5314                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5315                    isRestrictedBackupMode || !normalMode, app.persistent,
5316                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5317                    mCoreSettingsObserver.getCoreSettingsLocked());
5318            updateLruProcessLocked(app, false, null);
5319            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5320        } catch (Exception e) {
5321            // todo: Yikes!  What should we do?  For now we will try to
5322            // start another process, but that could easily get us in
5323            // an infinite loop of restarting processes...
5324            Slog.w(TAG, "Exception thrown during bind!", e);
5325
5326            app.resetPackageList(mProcessStats);
5327            app.unlinkDeathRecipient();
5328            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5329            return false;
5330        }
5331
5332        // Remove this record from the list of starting applications.
5333        mPersistentStartingProcesses.remove(app);
5334        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5335                "Attach application locked removing on hold: " + app);
5336        mProcessesOnHold.remove(app);
5337
5338        boolean badApp = false;
5339        boolean didSomething = false;
5340
5341        // See if the top visible activity is waiting to run in this process...
5342        if (normalMode) {
5343            try {
5344                if (mStackSupervisor.attachApplicationLocked(app)) {
5345                    didSomething = true;
5346                }
5347            } catch (Exception e) {
5348                badApp = true;
5349            }
5350        }
5351
5352        // Find any services that should be running in this process...
5353        if (!badApp) {
5354            try {
5355                didSomething |= mServices.attachApplicationLocked(app, processName);
5356            } catch (Exception e) {
5357                badApp = true;
5358            }
5359        }
5360
5361        // Check if a next-broadcast receiver is in this process...
5362        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5363            try {
5364                didSomething |= sendPendingBroadcastsLocked(app);
5365            } catch (Exception e) {
5366                // If the app died trying to launch the receiver we declare it 'bad'
5367                badApp = true;
5368            }
5369        }
5370
5371        // Check whether the next backup agent is in this process...
5372        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5373            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5374            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5375            try {
5376                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5377                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5378                        mBackupTarget.backupMode);
5379            } catch (Exception e) {
5380                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5381                e.printStackTrace();
5382            }
5383        }
5384
5385        if (badApp) {
5386            // todo: Also need to kill application to deal with all
5387            // kinds of exceptions.
5388            handleAppDiedLocked(app, false, true);
5389            return false;
5390        }
5391
5392        if (!didSomething) {
5393            updateOomAdjLocked();
5394        }
5395
5396        return true;
5397    }
5398
5399    @Override
5400    public final void attachApplication(IApplicationThread thread) {
5401        synchronized (this) {
5402            int callingPid = Binder.getCallingPid();
5403            final long origId = Binder.clearCallingIdentity();
5404            attachApplicationLocked(thread, callingPid);
5405            Binder.restoreCallingIdentity(origId);
5406        }
5407    }
5408
5409    @Override
5410    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5411        final long origId = Binder.clearCallingIdentity();
5412        synchronized (this) {
5413            ActivityStack stack = ActivityRecord.getStackLocked(token);
5414            if (stack != null) {
5415                ActivityRecord r =
5416                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5417                if (stopProfiling) {
5418                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5419                        try {
5420                            mProfileFd.close();
5421                        } catch (IOException e) {
5422                        }
5423                        clearProfilerLocked();
5424                    }
5425                }
5426            }
5427        }
5428        Binder.restoreCallingIdentity(origId);
5429    }
5430
5431    void enableScreenAfterBoot() {
5432        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5433                SystemClock.uptimeMillis());
5434        mWindowManager.enableScreenAfterBoot();
5435
5436        synchronized (this) {
5437            updateEventDispatchingLocked();
5438        }
5439    }
5440
5441    @Override
5442    public void showBootMessage(final CharSequence msg, final boolean always) {
5443        enforceNotIsolatedCaller("showBootMessage");
5444        mWindowManager.showBootMessage(msg, always);
5445    }
5446
5447    @Override
5448    public void dismissKeyguardOnNextActivity() {
5449        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5450        final long token = Binder.clearCallingIdentity();
5451        try {
5452            synchronized (this) {
5453                if (DEBUG_LOCKSCREEN) logLockScreen("");
5454                if (mLockScreenShown) {
5455                    mLockScreenShown = false;
5456                    comeOutOfSleepIfNeededLocked();
5457                }
5458                mStackSupervisor.setDismissKeyguard(true);
5459            }
5460        } finally {
5461            Binder.restoreCallingIdentity(token);
5462        }
5463    }
5464
5465    final void finishBooting() {
5466        // Register receivers to handle package update events
5467        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5468
5469        synchronized (this) {
5470            // Ensure that any processes we had put on hold are now started
5471            // up.
5472            final int NP = mProcessesOnHold.size();
5473            if (NP > 0) {
5474                ArrayList<ProcessRecord> procs =
5475                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5476                for (int ip=0; ip<NP; ip++) {
5477                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5478                            + procs.get(ip));
5479                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5480                }
5481            }
5482
5483            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5484                // Start looking for apps that are abusing wake locks.
5485                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5486                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5487                // Tell anyone interested that we are done booting!
5488                SystemProperties.set("sys.boot_completed", "1");
5489                SystemProperties.set("dev.bootcomplete", "1");
5490                for (int i=0; i<mStartedUsers.size(); i++) {
5491                    UserStartedState uss = mStartedUsers.valueAt(i);
5492                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5493                        uss.mState = UserStartedState.STATE_RUNNING;
5494                        final int userId = mStartedUsers.keyAt(i);
5495                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5496                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5497                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5498                        broadcastIntentLocked(null, null, intent, null,
5499                                new IIntentReceiver.Stub() {
5500                                    @Override
5501                                    public void performReceive(Intent intent, int resultCode,
5502                                            String data, Bundle extras, boolean ordered,
5503                                            boolean sticky, int sendingUser) {
5504                                        synchronized (ActivityManagerService.this) {
5505                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5506                                                    true, false);
5507                                        }
5508                                    }
5509                                },
5510                                0, null, null,
5511                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5512                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5513                                userId);
5514                    }
5515                }
5516                scheduleStartProfilesLocked();
5517            }
5518        }
5519    }
5520
5521    final void ensureBootCompleted() {
5522        boolean booting;
5523        boolean enableScreen;
5524        synchronized (this) {
5525            booting = mBooting;
5526            mBooting = false;
5527            enableScreen = !mBooted;
5528            mBooted = true;
5529        }
5530
5531        if (booting) {
5532            finishBooting();
5533        }
5534
5535        if (enableScreen) {
5536            enableScreenAfterBoot();
5537        }
5538    }
5539
5540    @Override
5541    public final void activityResumed(IBinder token) {
5542        final long origId = Binder.clearCallingIdentity();
5543        synchronized(this) {
5544            ActivityStack stack = ActivityRecord.getStackLocked(token);
5545            if (stack != null) {
5546                ActivityRecord.activityResumedLocked(token);
5547            }
5548        }
5549        Binder.restoreCallingIdentity(origId);
5550    }
5551
5552    @Override
5553    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5554        final long origId = Binder.clearCallingIdentity();
5555        synchronized(this) {
5556            ActivityStack stack = ActivityRecord.getStackLocked(token);
5557            if (stack != null) {
5558                stack.activityPausedLocked(token, false, persistentState);
5559            }
5560        }
5561        Binder.restoreCallingIdentity(origId);
5562    }
5563
5564    @Override
5565    public final void activityStopped(IBinder token, Bundle icicle,
5566            PersistableBundle persistentState, CharSequence description) {
5567        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5568
5569        // Refuse possible leaked file descriptors
5570        if (icicle != null && icicle.hasFileDescriptors()) {
5571            throw new IllegalArgumentException("File descriptors passed in Bundle");
5572        }
5573
5574        final long origId = Binder.clearCallingIdentity();
5575
5576        synchronized (this) {
5577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5578            if (r != null) {
5579                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5580            }
5581        }
5582
5583        trimApplications();
5584
5585        Binder.restoreCallingIdentity(origId);
5586    }
5587
5588    @Override
5589    public final void activityDestroyed(IBinder token) {
5590        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5591        synchronized (this) {
5592            ActivityStack stack = ActivityRecord.getStackLocked(token);
5593            if (stack != null) {
5594                stack.activityDestroyedLocked(token);
5595            }
5596        }
5597    }
5598
5599    @Override
5600    public String getCallingPackage(IBinder token) {
5601        synchronized (this) {
5602            ActivityRecord r = getCallingRecordLocked(token);
5603            return r != null ? r.info.packageName : null;
5604        }
5605    }
5606
5607    @Override
5608    public ComponentName getCallingActivity(IBinder token) {
5609        synchronized (this) {
5610            ActivityRecord r = getCallingRecordLocked(token);
5611            return r != null ? r.intent.getComponent() : null;
5612        }
5613    }
5614
5615    private ActivityRecord getCallingRecordLocked(IBinder token) {
5616        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5617        if (r == null) {
5618            return null;
5619        }
5620        return r.resultTo;
5621    }
5622
5623    @Override
5624    public ComponentName getActivityClassForToken(IBinder token) {
5625        synchronized(this) {
5626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5627            if (r == null) {
5628                return null;
5629            }
5630            return r.intent.getComponent();
5631        }
5632    }
5633
5634    @Override
5635    public String getPackageForToken(IBinder token) {
5636        synchronized(this) {
5637            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5638            if (r == null) {
5639                return null;
5640            }
5641            return r.packageName;
5642        }
5643    }
5644
5645    @Override
5646    public IIntentSender getIntentSender(int type,
5647            String packageName, IBinder token, String resultWho,
5648            int requestCode, Intent[] intents, String[] resolvedTypes,
5649            int flags, Bundle options, int userId) {
5650        enforceNotIsolatedCaller("getIntentSender");
5651        // Refuse possible leaked file descriptors
5652        if (intents != null) {
5653            if (intents.length < 1) {
5654                throw new IllegalArgumentException("Intents array length must be >= 1");
5655            }
5656            for (int i=0; i<intents.length; i++) {
5657                Intent intent = intents[i];
5658                if (intent != null) {
5659                    if (intent.hasFileDescriptors()) {
5660                        throw new IllegalArgumentException("File descriptors passed in Intent");
5661                    }
5662                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5663                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5664                        throw new IllegalArgumentException(
5665                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5666                    }
5667                    intents[i] = new Intent(intent);
5668                }
5669            }
5670            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5671                throw new IllegalArgumentException(
5672                        "Intent array length does not match resolvedTypes length");
5673            }
5674        }
5675        if (options != null) {
5676            if (options.hasFileDescriptors()) {
5677                throw new IllegalArgumentException("File descriptors passed in options");
5678            }
5679        }
5680
5681        synchronized(this) {
5682            int callingUid = Binder.getCallingUid();
5683            int origUserId = userId;
5684            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5685                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5686                    "getIntentSender", null);
5687            if (origUserId == UserHandle.USER_CURRENT) {
5688                // We don't want to evaluate this until the pending intent is
5689                // actually executed.  However, we do want to always do the
5690                // security checking for it above.
5691                userId = UserHandle.USER_CURRENT;
5692            }
5693            try {
5694                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5695                    int uid = AppGlobals.getPackageManager()
5696                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5697                    if (!UserHandle.isSameApp(callingUid, uid)) {
5698                        String msg = "Permission Denial: getIntentSender() from pid="
5699                            + Binder.getCallingPid()
5700                            + ", uid=" + Binder.getCallingUid()
5701                            + ", (need uid=" + uid + ")"
5702                            + " is not allowed to send as package " + packageName;
5703                        Slog.w(TAG, msg);
5704                        throw new SecurityException(msg);
5705                    }
5706                }
5707
5708                return getIntentSenderLocked(type, packageName, callingUid, userId,
5709                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5710
5711            } catch (RemoteException e) {
5712                throw new SecurityException(e);
5713            }
5714        }
5715    }
5716
5717    IIntentSender getIntentSenderLocked(int type, String packageName,
5718            int callingUid, int userId, IBinder token, String resultWho,
5719            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5720            Bundle options) {
5721        if (DEBUG_MU)
5722            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5723        ActivityRecord activity = null;
5724        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5725            activity = ActivityRecord.isInStackLocked(token);
5726            if (activity == null) {
5727                return null;
5728            }
5729            if (activity.finishing) {
5730                return null;
5731            }
5732        }
5733
5734        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5735        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5736        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5737        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5738                |PendingIntent.FLAG_UPDATE_CURRENT);
5739
5740        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5741                type, packageName, activity, resultWho,
5742                requestCode, intents, resolvedTypes, flags, options, userId);
5743        WeakReference<PendingIntentRecord> ref;
5744        ref = mIntentSenderRecords.get(key);
5745        PendingIntentRecord rec = ref != null ? ref.get() : null;
5746        if (rec != null) {
5747            if (!cancelCurrent) {
5748                if (updateCurrent) {
5749                    if (rec.key.requestIntent != null) {
5750                        rec.key.requestIntent.replaceExtras(intents != null ?
5751                                intents[intents.length - 1] : null);
5752                    }
5753                    if (intents != null) {
5754                        intents[intents.length-1] = rec.key.requestIntent;
5755                        rec.key.allIntents = intents;
5756                        rec.key.allResolvedTypes = resolvedTypes;
5757                    } else {
5758                        rec.key.allIntents = null;
5759                        rec.key.allResolvedTypes = null;
5760                    }
5761                }
5762                return rec;
5763            }
5764            rec.canceled = true;
5765            mIntentSenderRecords.remove(key);
5766        }
5767        if (noCreate) {
5768            return rec;
5769        }
5770        rec = new PendingIntentRecord(this, key, callingUid);
5771        mIntentSenderRecords.put(key, rec.ref);
5772        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5773            if (activity.pendingResults == null) {
5774                activity.pendingResults
5775                        = new HashSet<WeakReference<PendingIntentRecord>>();
5776            }
5777            activity.pendingResults.add(rec.ref);
5778        }
5779        return rec;
5780    }
5781
5782    @Override
5783    public void cancelIntentSender(IIntentSender sender) {
5784        if (!(sender instanceof PendingIntentRecord)) {
5785            return;
5786        }
5787        synchronized(this) {
5788            PendingIntentRecord rec = (PendingIntentRecord)sender;
5789            try {
5790                int uid = AppGlobals.getPackageManager()
5791                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5792                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5793                    String msg = "Permission Denial: cancelIntentSender() from pid="
5794                        + Binder.getCallingPid()
5795                        + ", uid=" + Binder.getCallingUid()
5796                        + " is not allowed to cancel packges "
5797                        + rec.key.packageName;
5798                    Slog.w(TAG, msg);
5799                    throw new SecurityException(msg);
5800                }
5801            } catch (RemoteException e) {
5802                throw new SecurityException(e);
5803            }
5804            cancelIntentSenderLocked(rec, true);
5805        }
5806    }
5807
5808    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5809        rec.canceled = true;
5810        mIntentSenderRecords.remove(rec.key);
5811        if (cleanActivity && rec.key.activity != null) {
5812            rec.key.activity.pendingResults.remove(rec.ref);
5813        }
5814    }
5815
5816    @Override
5817    public String getPackageForIntentSender(IIntentSender pendingResult) {
5818        if (!(pendingResult instanceof PendingIntentRecord)) {
5819            return null;
5820        }
5821        try {
5822            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5823            return res.key.packageName;
5824        } catch (ClassCastException e) {
5825        }
5826        return null;
5827    }
5828
5829    @Override
5830    public int getUidForIntentSender(IIntentSender sender) {
5831        if (sender instanceof PendingIntentRecord) {
5832            try {
5833                PendingIntentRecord res = (PendingIntentRecord)sender;
5834                return res.uid;
5835            } catch (ClassCastException e) {
5836            }
5837        }
5838        return -1;
5839    }
5840
5841    @Override
5842    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5843        if (!(pendingResult instanceof PendingIntentRecord)) {
5844            return false;
5845        }
5846        try {
5847            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5848            if (res.key.allIntents == null) {
5849                return false;
5850            }
5851            for (int i=0; i<res.key.allIntents.length; i++) {
5852                Intent intent = res.key.allIntents[i];
5853                if (intent.getPackage() != null && intent.getComponent() != null) {
5854                    return false;
5855                }
5856            }
5857            return true;
5858        } catch (ClassCastException e) {
5859        }
5860        return false;
5861    }
5862
5863    @Override
5864    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5865        if (!(pendingResult instanceof PendingIntentRecord)) {
5866            return false;
5867        }
5868        try {
5869            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5870            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5871                return true;
5872            }
5873            return false;
5874        } catch (ClassCastException e) {
5875        }
5876        return false;
5877    }
5878
5879    @Override
5880    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5881        if (!(pendingResult instanceof PendingIntentRecord)) {
5882            return null;
5883        }
5884        try {
5885            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5886            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5887        } catch (ClassCastException e) {
5888        }
5889        return null;
5890    }
5891
5892    @Override
5893    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5894        if (!(pendingResult instanceof PendingIntentRecord)) {
5895            return null;
5896        }
5897        try {
5898            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5899            Intent intent = res.key.requestIntent;
5900            if (intent != null) {
5901                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5902                        || res.lastTagPrefix.equals(prefix))) {
5903                    return res.lastTag;
5904                }
5905                res.lastTagPrefix = prefix;
5906                StringBuilder sb = new StringBuilder(128);
5907                if (prefix != null) {
5908                    sb.append(prefix);
5909                }
5910                if (intent.getAction() != null) {
5911                    sb.append(intent.getAction());
5912                } else if (intent.getComponent() != null) {
5913                    intent.getComponent().appendShortString(sb);
5914                } else {
5915                    sb.append("?");
5916                }
5917                return res.lastTag = sb.toString();
5918            }
5919        } catch (ClassCastException e) {
5920        }
5921        return null;
5922    }
5923
5924    @Override
5925    public void setProcessLimit(int max) {
5926        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5927                "setProcessLimit()");
5928        synchronized (this) {
5929            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5930            mProcessLimitOverride = max;
5931        }
5932        trimApplications();
5933    }
5934
5935    @Override
5936    public int getProcessLimit() {
5937        synchronized (this) {
5938            return mProcessLimitOverride;
5939        }
5940    }
5941
5942    void foregroundTokenDied(ForegroundToken token) {
5943        synchronized (ActivityManagerService.this) {
5944            synchronized (mPidsSelfLocked) {
5945                ForegroundToken cur
5946                    = mForegroundProcesses.get(token.pid);
5947                if (cur != token) {
5948                    return;
5949                }
5950                mForegroundProcesses.remove(token.pid);
5951                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5952                if (pr == null) {
5953                    return;
5954                }
5955                pr.forcingToForeground = null;
5956                updateProcessForegroundLocked(pr, false, false);
5957            }
5958            updateOomAdjLocked();
5959        }
5960    }
5961
5962    @Override
5963    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5964        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5965                "setProcessForeground()");
5966        synchronized(this) {
5967            boolean changed = false;
5968
5969            synchronized (mPidsSelfLocked) {
5970                ProcessRecord pr = mPidsSelfLocked.get(pid);
5971                if (pr == null && isForeground) {
5972                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5973                    return;
5974                }
5975                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5976                if (oldToken != null) {
5977                    oldToken.token.unlinkToDeath(oldToken, 0);
5978                    mForegroundProcesses.remove(pid);
5979                    if (pr != null) {
5980                        pr.forcingToForeground = null;
5981                    }
5982                    changed = true;
5983                }
5984                if (isForeground && token != null) {
5985                    ForegroundToken newToken = new ForegroundToken() {
5986                        @Override
5987                        public void binderDied() {
5988                            foregroundTokenDied(this);
5989                        }
5990                    };
5991                    newToken.pid = pid;
5992                    newToken.token = token;
5993                    try {
5994                        token.linkToDeath(newToken, 0);
5995                        mForegroundProcesses.put(pid, newToken);
5996                        pr.forcingToForeground = token;
5997                        changed = true;
5998                    } catch (RemoteException e) {
5999                        // If the process died while doing this, we will later
6000                        // do the cleanup with the process death link.
6001                    }
6002                }
6003            }
6004
6005            if (changed) {
6006                updateOomAdjLocked();
6007            }
6008        }
6009    }
6010
6011    // =========================================================
6012    // PERMISSIONS
6013    // =========================================================
6014
6015    static class PermissionController extends IPermissionController.Stub {
6016        ActivityManagerService mActivityManagerService;
6017        PermissionController(ActivityManagerService activityManagerService) {
6018            mActivityManagerService = activityManagerService;
6019        }
6020
6021        @Override
6022        public boolean checkPermission(String permission, int pid, int uid) {
6023            return mActivityManagerService.checkPermission(permission, pid,
6024                    uid) == PackageManager.PERMISSION_GRANTED;
6025        }
6026    }
6027
6028    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6029        @Override
6030        public int checkComponentPermission(String permission, int pid, int uid,
6031                int owningUid, boolean exported) {
6032            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6033                    owningUid, exported);
6034        }
6035
6036        @Override
6037        public Object getAMSLock() {
6038            return ActivityManagerService.this;
6039        }
6040    }
6041
6042    /**
6043     * This can be called with or without the global lock held.
6044     */
6045    int checkComponentPermission(String permission, int pid, int uid,
6046            int owningUid, boolean exported) {
6047        // We might be performing an operation on behalf of an indirect binder
6048        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6049        // client identity accordingly before proceeding.
6050        Identity tlsIdentity = sCallerIdentity.get();
6051        if (tlsIdentity != null) {
6052            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6053                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6054            uid = tlsIdentity.uid;
6055            pid = tlsIdentity.pid;
6056        }
6057
6058        if (pid == MY_PID) {
6059            return PackageManager.PERMISSION_GRANTED;
6060        }
6061
6062        return ActivityManager.checkComponentPermission(permission, uid,
6063                owningUid, exported);
6064    }
6065
6066    /**
6067     * As the only public entry point for permissions checking, this method
6068     * can enforce the semantic that requesting a check on a null global
6069     * permission is automatically denied.  (Internally a null permission
6070     * string is used when calling {@link #checkComponentPermission} in cases
6071     * when only uid-based security is needed.)
6072     *
6073     * This can be called with or without the global lock held.
6074     */
6075    @Override
6076    public int checkPermission(String permission, int pid, int uid) {
6077        if (permission == null) {
6078            return PackageManager.PERMISSION_DENIED;
6079        }
6080        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6081    }
6082
6083    /**
6084     * Binder IPC calls go through the public entry point.
6085     * This can be called with or without the global lock held.
6086     */
6087    int checkCallingPermission(String permission) {
6088        return checkPermission(permission,
6089                Binder.getCallingPid(),
6090                UserHandle.getAppId(Binder.getCallingUid()));
6091    }
6092
6093    /**
6094     * This can be called with or without the global lock held.
6095     */
6096    void enforceCallingPermission(String permission, String func) {
6097        if (checkCallingPermission(permission)
6098                == PackageManager.PERMISSION_GRANTED) {
6099            return;
6100        }
6101
6102        String msg = "Permission Denial: " + func + " from pid="
6103                + Binder.getCallingPid()
6104                + ", uid=" + Binder.getCallingUid()
6105                + " requires " + permission;
6106        Slog.w(TAG, msg);
6107        throw new SecurityException(msg);
6108    }
6109
6110    /**
6111     * Determine if UID is holding permissions required to access {@link Uri} in
6112     * the given {@link ProviderInfo}. Final permission checking is always done
6113     * in {@link ContentProvider}.
6114     */
6115    private final boolean checkHoldingPermissionsLocked(
6116            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6117        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6118                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6119        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6120            return false;
6121        }
6122        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6123    }
6124
6125    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6126            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6127        if (pi.applicationInfo.uid == uid) {
6128            return true;
6129        } else if (!pi.exported) {
6130            return false;
6131        }
6132
6133        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6134        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6135        try {
6136            // check if target holds top-level <provider> permissions
6137            if (!readMet && pi.readPermission != null && considerUidPermissions
6138                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6139                readMet = true;
6140            }
6141            if (!writeMet && pi.writePermission != null && considerUidPermissions
6142                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6143                writeMet = true;
6144            }
6145
6146            // track if unprotected read/write is allowed; any denied
6147            // <path-permission> below removes this ability
6148            boolean allowDefaultRead = pi.readPermission == null;
6149            boolean allowDefaultWrite = pi.writePermission == null;
6150
6151            // check if target holds any <path-permission> that match uri
6152            final PathPermission[] pps = pi.pathPermissions;
6153            if (pps != null) {
6154                final String path = grantUri.uri.getPath();
6155                int i = pps.length;
6156                while (i > 0 && (!readMet || !writeMet)) {
6157                    i--;
6158                    PathPermission pp = pps[i];
6159                    if (pp.match(path)) {
6160                        if (!readMet) {
6161                            final String pprperm = pp.getReadPermission();
6162                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6163                                    + pprperm + " for " + pp.getPath()
6164                                    + ": match=" + pp.match(path)
6165                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6166                            if (pprperm != null) {
6167                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6168                                        == PERMISSION_GRANTED) {
6169                                    readMet = true;
6170                                } else {
6171                                    allowDefaultRead = false;
6172                                }
6173                            }
6174                        }
6175                        if (!writeMet) {
6176                            final String ppwperm = pp.getWritePermission();
6177                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6178                                    + ppwperm + " for " + pp.getPath()
6179                                    + ": match=" + pp.match(path)
6180                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6181                            if (ppwperm != null) {
6182                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6183                                        == PERMISSION_GRANTED) {
6184                                    writeMet = true;
6185                                } else {
6186                                    allowDefaultWrite = false;
6187                                }
6188                            }
6189                        }
6190                    }
6191                }
6192            }
6193
6194            // grant unprotected <provider> read/write, if not blocked by
6195            // <path-permission> above
6196            if (allowDefaultRead) readMet = true;
6197            if (allowDefaultWrite) writeMet = true;
6198
6199        } catch (RemoteException e) {
6200            return false;
6201        }
6202
6203        return readMet && writeMet;
6204    }
6205
6206    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6207        ProviderInfo pi = null;
6208        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6209        if (cpr != null) {
6210            pi = cpr.info;
6211        } else {
6212            try {
6213                pi = AppGlobals.getPackageManager().resolveContentProvider(
6214                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6215            } catch (RemoteException ex) {
6216            }
6217        }
6218        return pi;
6219    }
6220
6221    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6222        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6223        if (targetUris != null) {
6224            return targetUris.get(grantUri);
6225        }
6226        return null;
6227    }
6228
6229    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6230            String targetPkg, int targetUid, GrantUri grantUri) {
6231        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6232        if (targetUris == null) {
6233            targetUris = Maps.newArrayMap();
6234            mGrantedUriPermissions.put(targetUid, targetUris);
6235        }
6236
6237        UriPermission perm = targetUris.get(grantUri);
6238        if (perm == null) {
6239            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6240            targetUris.put(grantUri, perm);
6241        }
6242
6243        return perm;
6244    }
6245
6246    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6247            final int modeFlags) {
6248        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6249        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6250                : UriPermission.STRENGTH_OWNED;
6251
6252        // Root gets to do everything.
6253        if (uid == 0) {
6254            return true;
6255        }
6256
6257        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6258        if (perms == null) return false;
6259
6260        // First look for exact match
6261        final UriPermission exactPerm = perms.get(grantUri);
6262        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6263            return true;
6264        }
6265
6266        // No exact match, look for prefixes
6267        final int N = perms.size();
6268        for (int i = 0; i < N; i++) {
6269            final UriPermission perm = perms.valueAt(i);
6270            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6271                    && perm.getStrength(modeFlags) >= minStrength) {
6272                return true;
6273            }
6274        }
6275
6276        return false;
6277    }
6278
6279    @Override
6280    public int checkUriPermission(Uri uri, int pid, int uid,
6281            final int modeFlags, int userId) {
6282        enforceNotIsolatedCaller("checkUriPermission");
6283
6284        // Another redirected-binder-call permissions check as in
6285        // {@link checkComponentPermission}.
6286        Identity tlsIdentity = sCallerIdentity.get();
6287        if (tlsIdentity != null) {
6288            uid = tlsIdentity.uid;
6289            pid = tlsIdentity.pid;
6290        }
6291
6292        // Our own process gets to do everything.
6293        if (pid == MY_PID) {
6294            return PackageManager.PERMISSION_GRANTED;
6295        }
6296        synchronized (this) {
6297            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6298                    ? PackageManager.PERMISSION_GRANTED
6299                    : PackageManager.PERMISSION_DENIED;
6300        }
6301    }
6302
6303    /**
6304     * Check if the targetPkg can be granted permission to access uri by
6305     * the callingUid using the given modeFlags.  Throws a security exception
6306     * if callingUid is not allowed to do this.  Returns the uid of the target
6307     * if the URI permission grant should be performed; returns -1 if it is not
6308     * needed (for example targetPkg already has permission to access the URI).
6309     * If you already know the uid of the target, you can supply it in
6310     * lastTargetUid else set that to -1.
6311     */
6312    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6313            final int modeFlags, int lastTargetUid) {
6314        if (!Intent.isAccessUriMode(modeFlags)) {
6315            return -1;
6316        }
6317
6318        if (targetPkg != null) {
6319            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6320                    "Checking grant " + targetPkg + " permission to " + grantUri);
6321        }
6322
6323        final IPackageManager pm = AppGlobals.getPackageManager();
6324
6325        // If this is not a content: uri, we can't do anything with it.
6326        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6327            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6328                    "Can't grant URI permission for non-content URI: " + grantUri);
6329            return -1;
6330        }
6331
6332        final String authority = grantUri.uri.getAuthority();
6333        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6334        if (pi == null) {
6335            Slog.w(TAG, "No content provider found for permission check: " +
6336                    grantUri.uri.toSafeString());
6337            return -1;
6338        }
6339
6340        int targetUid = lastTargetUid;
6341        if (targetUid < 0 && targetPkg != null) {
6342            try {
6343                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6344                if (targetUid < 0) {
6345                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6346                            "Can't grant URI permission no uid for: " + targetPkg);
6347                    return -1;
6348                }
6349            } catch (RemoteException ex) {
6350                return -1;
6351            }
6352        }
6353
6354        if (targetUid >= 0) {
6355            // First...  does the target actually need this permission?
6356            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6357                // No need to grant the target this permission.
6358                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6359                        "Target " + targetPkg + " already has full permission to " + grantUri);
6360                return -1;
6361            }
6362        } else {
6363            // First...  there is no target package, so can anyone access it?
6364            boolean allowed = pi.exported;
6365            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6366                if (pi.readPermission != null) {
6367                    allowed = false;
6368                }
6369            }
6370            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6371                if (pi.writePermission != null) {
6372                    allowed = false;
6373                }
6374            }
6375            if (allowed) {
6376                return -1;
6377            }
6378        }
6379
6380        /* There is a special cross user grant if:
6381         * - The target is on another user.
6382         * - Apps on the current user can access the uri without any uid permissions.
6383         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6384         * grant uri permissions.
6385         */
6386        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6387                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6388                modeFlags, false /*without considering the uid permissions*/);
6389
6390        // Second...  is the provider allowing granting of URI permissions?
6391        if (!specialCrossUserGrant) {
6392            if (!pi.grantUriPermissions) {
6393                throw new SecurityException("Provider " + pi.packageName
6394                        + "/" + pi.name
6395                        + " does not allow granting of Uri permissions (uri "
6396                        + grantUri + ")");
6397            }
6398            if (pi.uriPermissionPatterns != null) {
6399                final int N = pi.uriPermissionPatterns.length;
6400                boolean allowed = false;
6401                for (int i=0; i<N; i++) {
6402                    if (pi.uriPermissionPatterns[i] != null
6403                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6404                        allowed = true;
6405                        break;
6406                    }
6407                }
6408                if (!allowed) {
6409                    throw new SecurityException("Provider " + pi.packageName
6410                            + "/" + pi.name
6411                            + " does not allow granting of permission to path of Uri "
6412                            + grantUri);
6413                }
6414            }
6415        }
6416
6417        // Third...  does the caller itself have permission to access
6418        // this uri?
6419        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6420            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6421                // Require they hold a strong enough Uri permission
6422                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6423                    throw new SecurityException("Uid " + callingUid
6424                            + " does not have permission to uri " + grantUri);
6425                }
6426            }
6427        }
6428        return targetUid;
6429    }
6430
6431    @Override
6432    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6433            final int modeFlags, int userId) {
6434        enforceNotIsolatedCaller("checkGrantUriPermission");
6435        synchronized(this) {
6436            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6437                    new GrantUri(userId, uri, false), modeFlags, -1);
6438        }
6439    }
6440
6441    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6442            final int modeFlags, UriPermissionOwner owner) {
6443        if (!Intent.isAccessUriMode(modeFlags)) {
6444            return;
6445        }
6446
6447        // So here we are: the caller has the assumed permission
6448        // to the uri, and the target doesn't.  Let's now give this to
6449        // the target.
6450
6451        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6452                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6453
6454        final String authority = grantUri.uri.getAuthority();
6455        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6456        if (pi == null) {
6457            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6458            return;
6459        }
6460
6461        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6462            grantUri.prefix = true;
6463        }
6464        final UriPermission perm = findOrCreateUriPermissionLocked(
6465                pi.packageName, targetPkg, targetUid, grantUri);
6466        perm.grantModes(modeFlags, owner);
6467    }
6468
6469    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6470            final int modeFlags, UriPermissionOwner owner) {
6471        if (targetPkg == null) {
6472            throw new NullPointerException("targetPkg");
6473        }
6474
6475        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6476                -1);
6477        if (targetUid < 0) {
6478            return;
6479        }
6480
6481        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6482                owner);
6483    }
6484
6485    static class NeededUriGrants extends ArrayList<GrantUri> {
6486        final String targetPkg;
6487        final int targetUid;
6488        final int flags;
6489
6490        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6491            this.targetPkg = targetPkg;
6492            this.targetUid = targetUid;
6493            this.flags = flags;
6494        }
6495    }
6496
6497    /**
6498     * Like checkGrantUriPermissionLocked, but takes an Intent.
6499     */
6500    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6501            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6502        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6503                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6504                + " clip=" + (intent != null ? intent.getClipData() : null)
6505                + " from " + intent + "; flags=0x"
6506                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6507
6508        if (targetPkg == null) {
6509            throw new NullPointerException("targetPkg");
6510        }
6511
6512        if (intent == null) {
6513            return null;
6514        }
6515        Uri data = intent.getData();
6516        ClipData clip = intent.getClipData();
6517        if (data == null && clip == null) {
6518            return null;
6519        }
6520        final IPackageManager pm = AppGlobals.getPackageManager();
6521        int targetUid;
6522        if (needed != null) {
6523            targetUid = needed.targetUid;
6524        } else {
6525            try {
6526                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6527            } catch (RemoteException ex) {
6528                return null;
6529            }
6530            if (targetUid < 0) {
6531                if (DEBUG_URI_PERMISSION) {
6532                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6533                            + " on user " + targetUserId);
6534                }
6535                return null;
6536            }
6537        }
6538        if (data != null) {
6539            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6540            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6541                    targetUid);
6542            if (targetUid > 0) {
6543                if (needed == null) {
6544                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6545                }
6546                needed.add(grantUri);
6547            }
6548        }
6549        if (clip != null) {
6550            for (int i=0; i<clip.getItemCount(); i++) {
6551                Uri uri = clip.getItemAt(i).getUri();
6552                if (uri != null) {
6553                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6554                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6555                            targetUid);
6556                    if (targetUid > 0) {
6557                        if (needed == null) {
6558                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6559                        }
6560                        needed.add(grantUri);
6561                    }
6562                } else {
6563                    Intent clipIntent = clip.getItemAt(i).getIntent();
6564                    if (clipIntent != null) {
6565                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6566                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6567                        if (newNeeded != null) {
6568                            needed = newNeeded;
6569                        }
6570                    }
6571                }
6572            }
6573        }
6574
6575        return needed;
6576    }
6577
6578    /**
6579     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6580     */
6581    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6582            UriPermissionOwner owner) {
6583        if (needed != null) {
6584            for (int i=0; i<needed.size(); i++) {
6585                GrantUri grantUri = needed.get(i);
6586                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6587                        grantUri, needed.flags, owner);
6588            }
6589        }
6590    }
6591
6592    void grantUriPermissionFromIntentLocked(int callingUid,
6593            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6594        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6595                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6596        if (needed == null) {
6597            return;
6598        }
6599
6600        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6601    }
6602
6603    @Override
6604    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6605            final int modeFlags, int userId) {
6606        enforceNotIsolatedCaller("grantUriPermission");
6607        GrantUri grantUri = new GrantUri(userId, uri, false);
6608        synchronized(this) {
6609            final ProcessRecord r = getRecordForAppLocked(caller);
6610            if (r == null) {
6611                throw new SecurityException("Unable to find app for caller "
6612                        + caller
6613                        + " when granting permission to uri " + grantUri);
6614            }
6615            if (targetPkg == null) {
6616                throw new IllegalArgumentException("null target");
6617            }
6618            if (grantUri == null) {
6619                throw new IllegalArgumentException("null uri");
6620            }
6621
6622            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6623                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6624                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6625                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6626
6627            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6628        }
6629    }
6630
6631    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6632        if (perm.modeFlags == 0) {
6633            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6634                    perm.targetUid);
6635            if (perms != null) {
6636                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6637                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6638
6639                perms.remove(perm.uri);
6640                if (perms.isEmpty()) {
6641                    mGrantedUriPermissions.remove(perm.targetUid);
6642                }
6643            }
6644        }
6645    }
6646
6647    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6648        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6649
6650        final IPackageManager pm = AppGlobals.getPackageManager();
6651        final String authority = grantUri.uri.getAuthority();
6652        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6653        if (pi == null) {
6654            Slog.w(TAG, "No content provider found for permission revoke: "
6655                    + grantUri.toSafeString());
6656            return;
6657        }
6658
6659        // Does the caller have this permission on the URI?
6660        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6661            // Right now, if you are not the original owner of the permission,
6662            // you are not allowed to revoke it.
6663            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6664                throw new SecurityException("Uid " + callingUid
6665                        + " does not have permission to uri " + grantUri);
6666            //}
6667        }
6668
6669        boolean persistChanged = false;
6670
6671        // Go through all of the permissions and remove any that match.
6672        int N = mGrantedUriPermissions.size();
6673        for (int i = 0; i < N; i++) {
6674            final int targetUid = mGrantedUriPermissions.keyAt(i);
6675            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6676
6677            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6678                final UriPermission perm = it.next();
6679                if (perm.uri.sourceUserId == grantUri.sourceUserId
6680                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6681                    if (DEBUG_URI_PERMISSION)
6682                        Slog.v(TAG,
6683                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6684                    persistChanged |= perm.revokeModes(
6685                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6686                    if (perm.modeFlags == 0) {
6687                        it.remove();
6688                    }
6689                }
6690            }
6691
6692            if (perms.isEmpty()) {
6693                mGrantedUriPermissions.remove(targetUid);
6694                N--;
6695                i--;
6696            }
6697        }
6698
6699        if (persistChanged) {
6700            schedulePersistUriGrants();
6701        }
6702    }
6703
6704    @Override
6705    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6706            int userId) {
6707        enforceNotIsolatedCaller("revokeUriPermission");
6708        synchronized(this) {
6709            final ProcessRecord r = getRecordForAppLocked(caller);
6710            if (r == null) {
6711                throw new SecurityException("Unable to find app for caller "
6712                        + caller
6713                        + " when revoking permission to uri " + uri);
6714            }
6715            if (uri == null) {
6716                Slog.w(TAG, "revokeUriPermission: null uri");
6717                return;
6718            }
6719
6720            if (!Intent.isAccessUriMode(modeFlags)) {
6721                return;
6722            }
6723
6724            final IPackageManager pm = AppGlobals.getPackageManager();
6725            final String authority = uri.getAuthority();
6726            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6727            if (pi == null) {
6728                Slog.w(TAG, "No content provider found for permission revoke: "
6729                        + uri.toSafeString());
6730                return;
6731            }
6732
6733            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6734        }
6735    }
6736
6737    /**
6738     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6739     * given package.
6740     *
6741     * @param packageName Package name to match, or {@code null} to apply to all
6742     *            packages.
6743     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6744     *            to all users.
6745     * @param persistable If persistable grants should be removed.
6746     */
6747    private void removeUriPermissionsForPackageLocked(
6748            String packageName, int userHandle, boolean persistable) {
6749        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6750            throw new IllegalArgumentException("Must narrow by either package or user");
6751        }
6752
6753        boolean persistChanged = false;
6754
6755        int N = mGrantedUriPermissions.size();
6756        for (int i = 0; i < N; i++) {
6757            final int targetUid = mGrantedUriPermissions.keyAt(i);
6758            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6759
6760            // Only inspect grants matching user
6761            if (userHandle == UserHandle.USER_ALL
6762                    || userHandle == UserHandle.getUserId(targetUid)) {
6763                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6764                    final UriPermission perm = it.next();
6765
6766                    // Only inspect grants matching package
6767                    if (packageName == null || perm.sourcePkg.equals(packageName)
6768                            || perm.targetPkg.equals(packageName)) {
6769                        persistChanged |= perm.revokeModes(
6770                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6771
6772                        // Only remove when no modes remain; any persisted grants
6773                        // will keep this alive.
6774                        if (perm.modeFlags == 0) {
6775                            it.remove();
6776                        }
6777                    }
6778                }
6779
6780                if (perms.isEmpty()) {
6781                    mGrantedUriPermissions.remove(targetUid);
6782                    N--;
6783                    i--;
6784                }
6785            }
6786        }
6787
6788        if (persistChanged) {
6789            schedulePersistUriGrants();
6790        }
6791    }
6792
6793    @Override
6794    public IBinder newUriPermissionOwner(String name) {
6795        enforceNotIsolatedCaller("newUriPermissionOwner");
6796        synchronized(this) {
6797            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6798            return owner.getExternalTokenLocked();
6799        }
6800    }
6801
6802    @Override
6803    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6804            final int modeFlags, int userId) {
6805        synchronized(this) {
6806            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6807            if (owner == null) {
6808                throw new IllegalArgumentException("Unknown owner: " + token);
6809            }
6810            if (fromUid != Binder.getCallingUid()) {
6811                if (Binder.getCallingUid() != Process.myUid()) {
6812                    // Only system code can grant URI permissions on behalf
6813                    // of other users.
6814                    throw new SecurityException("nice try");
6815                }
6816            }
6817            if (targetPkg == null) {
6818                throw new IllegalArgumentException("null target");
6819            }
6820            if (uri == null) {
6821                throw new IllegalArgumentException("null uri");
6822            }
6823
6824            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6825                    modeFlags, owner);
6826        }
6827    }
6828
6829    @Override
6830    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6831        synchronized(this) {
6832            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6833            if (owner == null) {
6834                throw new IllegalArgumentException("Unknown owner: " + token);
6835            }
6836
6837            if (uri == null) {
6838                owner.removeUriPermissionsLocked(mode);
6839            } else {
6840                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6841            }
6842        }
6843    }
6844
6845    private void schedulePersistUriGrants() {
6846        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6847            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6848                    10 * DateUtils.SECOND_IN_MILLIS);
6849        }
6850    }
6851
6852    private void writeGrantedUriPermissions() {
6853        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6854
6855        // Snapshot permissions so we can persist without lock
6856        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6857        synchronized (this) {
6858            final int size = mGrantedUriPermissions.size();
6859            for (int i = 0; i < size; i++) {
6860                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6861                for (UriPermission perm : perms.values()) {
6862                    if (perm.persistedModeFlags != 0) {
6863                        persist.add(perm.snapshot());
6864                    }
6865                }
6866            }
6867        }
6868
6869        FileOutputStream fos = null;
6870        try {
6871            fos = mGrantFile.startWrite();
6872
6873            XmlSerializer out = new FastXmlSerializer();
6874            out.setOutput(fos, "utf-8");
6875            out.startDocument(null, true);
6876            out.startTag(null, TAG_URI_GRANTS);
6877            for (UriPermission.Snapshot perm : persist) {
6878                out.startTag(null, TAG_URI_GRANT);
6879                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6880                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6881                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6882                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6883                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6884                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6885                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6886                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6887                out.endTag(null, TAG_URI_GRANT);
6888            }
6889            out.endTag(null, TAG_URI_GRANTS);
6890            out.endDocument();
6891
6892            mGrantFile.finishWrite(fos);
6893        } catch (IOException e) {
6894            if (fos != null) {
6895                mGrantFile.failWrite(fos);
6896            }
6897        }
6898    }
6899
6900    private void readGrantedUriPermissionsLocked() {
6901        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6902
6903        final long now = System.currentTimeMillis();
6904
6905        FileInputStream fis = null;
6906        try {
6907            fis = mGrantFile.openRead();
6908            final XmlPullParser in = Xml.newPullParser();
6909            in.setInput(fis, null);
6910
6911            int type;
6912            while ((type = in.next()) != END_DOCUMENT) {
6913                final String tag = in.getName();
6914                if (type == START_TAG) {
6915                    if (TAG_URI_GRANT.equals(tag)) {
6916                        final int sourceUserId;
6917                        final int targetUserId;
6918                        final int userHandle = readIntAttribute(in,
6919                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6920                        if (userHandle != UserHandle.USER_NULL) {
6921                            // For backwards compatibility.
6922                            sourceUserId = userHandle;
6923                            targetUserId = userHandle;
6924                        } else {
6925                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6926                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6927                        }
6928                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6929                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6930                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6931                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6932                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6933                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6934
6935                        // Sanity check that provider still belongs to source package
6936                        final ProviderInfo pi = getProviderInfoLocked(
6937                                uri.getAuthority(), sourceUserId);
6938                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6939                            int targetUid = -1;
6940                            try {
6941                                targetUid = AppGlobals.getPackageManager()
6942                                        .getPackageUid(targetPkg, targetUserId);
6943                            } catch (RemoteException e) {
6944                            }
6945                            if (targetUid != -1) {
6946                                final UriPermission perm = findOrCreateUriPermissionLocked(
6947                                        sourcePkg, targetPkg, targetUid,
6948                                        new GrantUri(sourceUserId, uri, prefix));
6949                                perm.initPersistedModes(modeFlags, createdTime);
6950                            }
6951                        } else {
6952                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6953                                    + " but instead found " + pi);
6954                        }
6955                    }
6956                }
6957            }
6958        } catch (FileNotFoundException e) {
6959            // Missing grants is okay
6960        } catch (IOException e) {
6961            Log.wtf(TAG, "Failed reading Uri grants", e);
6962        } catch (XmlPullParserException e) {
6963            Log.wtf(TAG, "Failed reading Uri grants", e);
6964        } finally {
6965            IoUtils.closeQuietly(fis);
6966        }
6967    }
6968
6969    @Override
6970    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6971        enforceNotIsolatedCaller("takePersistableUriPermission");
6972
6973        Preconditions.checkFlagsArgument(modeFlags,
6974                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6975
6976        synchronized (this) {
6977            final int callingUid = Binder.getCallingUid();
6978            boolean persistChanged = false;
6979            GrantUri grantUri = new GrantUri(userId, uri, false);
6980
6981            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6982                    new GrantUri(userId, uri, false));
6983            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6984                    new GrantUri(userId, uri, true));
6985
6986            final boolean exactValid = (exactPerm != null)
6987                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6988            final boolean prefixValid = (prefixPerm != null)
6989                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6990
6991            if (!(exactValid || prefixValid)) {
6992                throw new SecurityException("No persistable permission grants found for UID "
6993                        + callingUid + " and Uri " + grantUri.toSafeString());
6994            }
6995
6996            if (exactValid) {
6997                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6998            }
6999            if (prefixValid) {
7000                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7001            }
7002
7003            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7004
7005            if (persistChanged) {
7006                schedulePersistUriGrants();
7007            }
7008        }
7009    }
7010
7011    @Override
7012    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7013        enforceNotIsolatedCaller("releasePersistableUriPermission");
7014
7015        Preconditions.checkFlagsArgument(modeFlags,
7016                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7017
7018        synchronized (this) {
7019            final int callingUid = Binder.getCallingUid();
7020            boolean persistChanged = false;
7021
7022            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7023                    new GrantUri(userId, uri, false));
7024            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7025                    new GrantUri(userId, uri, true));
7026            if (exactPerm == null && prefixPerm == null) {
7027                throw new SecurityException("No permission grants found for UID " + callingUid
7028                        + " and Uri " + uri.toSafeString());
7029            }
7030
7031            if (exactPerm != null) {
7032                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7033                removeUriPermissionIfNeededLocked(exactPerm);
7034            }
7035            if (prefixPerm != null) {
7036                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7037                removeUriPermissionIfNeededLocked(prefixPerm);
7038            }
7039
7040            if (persistChanged) {
7041                schedulePersistUriGrants();
7042            }
7043        }
7044    }
7045
7046    /**
7047     * Prune any older {@link UriPermission} for the given UID until outstanding
7048     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7049     *
7050     * @return if any mutations occured that require persisting.
7051     */
7052    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7053        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7054        if (perms == null) return false;
7055        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7056
7057        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7058        for (UriPermission perm : perms.values()) {
7059            if (perm.persistedModeFlags != 0) {
7060                persisted.add(perm);
7061            }
7062        }
7063
7064        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7065        if (trimCount <= 0) return false;
7066
7067        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7068        for (int i = 0; i < trimCount; i++) {
7069            final UriPermission perm = persisted.get(i);
7070
7071            if (DEBUG_URI_PERMISSION) {
7072                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7073            }
7074
7075            perm.releasePersistableModes(~0);
7076            removeUriPermissionIfNeededLocked(perm);
7077        }
7078
7079        return true;
7080    }
7081
7082    @Override
7083    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7084            String packageName, boolean incoming) {
7085        enforceNotIsolatedCaller("getPersistedUriPermissions");
7086        Preconditions.checkNotNull(packageName, "packageName");
7087
7088        final int callingUid = Binder.getCallingUid();
7089        final IPackageManager pm = AppGlobals.getPackageManager();
7090        try {
7091            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7092            if (packageUid != callingUid) {
7093                throw new SecurityException(
7094                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7095            }
7096        } catch (RemoteException e) {
7097            throw new SecurityException("Failed to verify package name ownership");
7098        }
7099
7100        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7101        synchronized (this) {
7102            if (incoming) {
7103                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7104                        callingUid);
7105                if (perms == null) {
7106                    Slog.w(TAG, "No permission grants found for " + packageName);
7107                } else {
7108                    for (UriPermission perm : perms.values()) {
7109                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7110                            result.add(perm.buildPersistedPublicApiObject());
7111                        }
7112                    }
7113                }
7114            } else {
7115                final int size = mGrantedUriPermissions.size();
7116                for (int i = 0; i < size; i++) {
7117                    final ArrayMap<GrantUri, UriPermission> perms =
7118                            mGrantedUriPermissions.valueAt(i);
7119                    for (UriPermission perm : perms.values()) {
7120                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7121                            result.add(perm.buildPersistedPublicApiObject());
7122                        }
7123                    }
7124                }
7125            }
7126        }
7127        return new ParceledListSlice<android.content.UriPermission>(result);
7128    }
7129
7130    @Override
7131    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7132        synchronized (this) {
7133            ProcessRecord app =
7134                who != null ? getRecordForAppLocked(who) : null;
7135            if (app == null) return;
7136
7137            Message msg = Message.obtain();
7138            msg.what = WAIT_FOR_DEBUGGER_MSG;
7139            msg.obj = app;
7140            msg.arg1 = waiting ? 1 : 0;
7141            mHandler.sendMessage(msg);
7142        }
7143    }
7144
7145    @Override
7146    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7147        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7148        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7149        outInfo.availMem = Process.getFreeMemory();
7150        outInfo.totalMem = Process.getTotalMemory();
7151        outInfo.threshold = homeAppMem;
7152        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7153        outInfo.hiddenAppThreshold = cachedAppMem;
7154        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7155                ProcessList.SERVICE_ADJ);
7156        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7157                ProcessList.VISIBLE_APP_ADJ);
7158        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7159                ProcessList.FOREGROUND_APP_ADJ);
7160    }
7161
7162    // =========================================================
7163    // TASK MANAGEMENT
7164    // =========================================================
7165
7166    @Override
7167    public List<IAppTask> getAppTasks() {
7168        int callingUid = Binder.getCallingUid();
7169        long ident = Binder.clearCallingIdentity();
7170        synchronized(this) {
7171            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7172            try {
7173                if (localLOGV) Slog.v(TAG, "getAppTasks");
7174
7175                final int N = mRecentTasks.size();
7176                for (int i = 0; i < N; i++) {
7177                    TaskRecord tr = mRecentTasks.get(i);
7178                    // Skip tasks that are not created by the caller
7179                    if (tr.creatorUid == callingUid) {
7180                        ActivityManager.RecentTaskInfo taskInfo =
7181                                createRecentTaskInfoFromTaskRecord(tr);
7182                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7183                        list.add(taskImpl);
7184                    }
7185                }
7186            } finally {
7187                Binder.restoreCallingIdentity(ident);
7188            }
7189            return list;
7190        }
7191    }
7192
7193    @Override
7194    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7195        final int callingUid = Binder.getCallingUid();
7196        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7197
7198        synchronized(this) {
7199            if (localLOGV) Slog.v(
7200                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7201
7202            final boolean allowed = checkCallingPermission(
7203                    android.Manifest.permission.GET_TASKS)
7204                    == PackageManager.PERMISSION_GRANTED;
7205            if (!allowed) {
7206                Slog.w(TAG, "getTasks: caller " + callingUid
7207                        + " does not hold GET_TASKS; limiting output");
7208            }
7209
7210            // TODO: Improve with MRU list from all ActivityStacks.
7211            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7212        }
7213
7214        return list;
7215    }
7216
7217    TaskRecord getMostRecentTask() {
7218        return mRecentTasks.get(0);
7219    }
7220
7221    /**
7222     * Creates a new RecentTaskInfo from a TaskRecord.
7223     */
7224    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7225        // Update the task description to reflect any changes in the task stack
7226        tr.updateTaskDescription();
7227
7228        // Compose the recent task info
7229        ActivityManager.RecentTaskInfo rti
7230                = new ActivityManager.RecentTaskInfo();
7231        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7232        rti.persistentId = tr.taskId;
7233        rti.baseIntent = new Intent(tr.getBaseIntent());
7234        rti.origActivity = tr.origActivity;
7235        rti.description = tr.lastDescription;
7236        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7237        rti.userId = tr.userId;
7238        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7239        return rti;
7240    }
7241
7242    @Override
7243    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7244            int flags, int userId) {
7245        final int callingUid = Binder.getCallingUid();
7246        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7247                false, true, "getRecentTasks", null);
7248
7249        synchronized (this) {
7250            final boolean allowed = checkCallingPermission(
7251                    android.Manifest.permission.GET_TASKS)
7252                    == PackageManager.PERMISSION_GRANTED;
7253            if (!allowed) {
7254                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7255                        + " does not hold GET_TASKS; limiting output");
7256            }
7257            final boolean detailed = checkCallingPermission(
7258                    android.Manifest.permission.GET_DETAILED_TASKS)
7259                    == PackageManager.PERMISSION_GRANTED;
7260
7261            IPackageManager pm = AppGlobals.getPackageManager();
7262
7263            final int N = mRecentTasks.size();
7264            ArrayList<ActivityManager.RecentTaskInfo> res
7265                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7266                            maxNum < N ? maxNum : N);
7267
7268            final Set<Integer> includedUsers;
7269            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7270                includedUsers = getProfileIdsLocked(userId);
7271            } else {
7272                includedUsers = new HashSet<Integer>();
7273            }
7274            includedUsers.add(Integer.valueOf(userId));
7275            for (int i=0; i<N && maxNum > 0; i++) {
7276                TaskRecord tr = mRecentTasks.get(i);
7277                // Only add calling user or related users recent tasks
7278                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7279
7280                // Return the entry if desired by the caller.  We always return
7281                // the first entry, because callers always expect this to be the
7282                // foreground app.  We may filter others if the caller has
7283                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7284                // we should exclude the entry.
7285
7286                if (i == 0
7287                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7288                        || (tr.intent == null)
7289                        || ((tr.intent.getFlags()
7290                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7291                    if (!allowed) {
7292                        // If the caller doesn't have the GET_TASKS permission, then only
7293                        // allow them to see a small subset of tasks -- their own and home.
7294                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7295                            continue;
7296                        }
7297                    }
7298                    if (tr.intent != null &&
7299                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7300                            != 0 && tr.getTopActivity() == null) {
7301                        // Don't include auto remove tasks that are finished or finishing.
7302                        continue;
7303                    }
7304
7305                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7306                    if (!detailed) {
7307                        rti.baseIntent.replaceExtras((Bundle)null);
7308                    }
7309
7310                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7311                        // Check whether this activity is currently available.
7312                        try {
7313                            if (rti.origActivity != null) {
7314                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7315                                        == null) {
7316                                    continue;
7317                                }
7318                            } else if (rti.baseIntent != null) {
7319                                if (pm.queryIntentActivities(rti.baseIntent,
7320                                        null, 0, userId) == null) {
7321                                    continue;
7322                                }
7323                            }
7324                        } catch (RemoteException e) {
7325                            // Will never happen.
7326                        }
7327                    }
7328
7329                    res.add(rti);
7330                    maxNum--;
7331                }
7332            }
7333            return res;
7334        }
7335    }
7336
7337    private TaskRecord recentTaskForIdLocked(int id) {
7338        final int N = mRecentTasks.size();
7339            for (int i=0; i<N; i++) {
7340                TaskRecord tr = mRecentTasks.get(i);
7341                if (tr.taskId == id) {
7342                    return tr;
7343                }
7344            }
7345            return null;
7346    }
7347
7348    @Override
7349    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7350        synchronized (this) {
7351            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7352                    "getTaskThumbnails()");
7353            TaskRecord tr = recentTaskForIdLocked(id);
7354            if (tr != null) {
7355                return tr.getTaskThumbnailsLocked();
7356            }
7357        }
7358        return null;
7359    }
7360
7361    @Override
7362    public Bitmap getTaskTopThumbnail(int id) {
7363        synchronized (this) {
7364            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7365                    "getTaskTopThumbnail()");
7366            TaskRecord tr = recentTaskForIdLocked(id);
7367            if (tr != null) {
7368                return tr.getTaskTopThumbnailLocked();
7369            }
7370        }
7371        return null;
7372    }
7373
7374    @Override
7375    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7376        synchronized (this) {
7377            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7378            if (r != null) {
7379                r.taskDescription = td;
7380                r.task.updateTaskDescription();
7381            }
7382        }
7383    }
7384
7385    @Override
7386    public boolean removeSubTask(int taskId, int subTaskIndex) {
7387        synchronized (this) {
7388            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7389                    "removeSubTask()");
7390            long ident = Binder.clearCallingIdentity();
7391            try {
7392                TaskRecord tr = recentTaskForIdLocked(taskId);
7393                if (tr != null) {
7394                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7395                }
7396                return false;
7397            } finally {
7398                Binder.restoreCallingIdentity(ident);
7399            }
7400        }
7401    }
7402
7403    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7404        if (!pr.killedByAm) {
7405            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7406            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7407                    pr.processName, pr.setAdj, reason);
7408            pr.killedByAm = true;
7409            Process.killProcessQuiet(pr.pid);
7410        }
7411    }
7412
7413    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7414        tr.disposeThumbnail();
7415        mRecentTasks.remove(tr);
7416        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7417        Intent baseIntent = new Intent(
7418                tr.intent != null ? tr.intent : tr.affinityIntent);
7419        ComponentName component = baseIntent.getComponent();
7420        if (component == null) {
7421            Slog.w(TAG, "Now component for base intent of task: " + tr);
7422            return;
7423        }
7424
7425        // Find any running services associated with this app.
7426        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7427
7428        if (killProcesses) {
7429            // Find any running processes associated with this app.
7430            final String pkg = component.getPackageName();
7431            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7432            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7433            for (int i=0; i<pmap.size(); i++) {
7434                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7435                for (int j=0; j<uids.size(); j++) {
7436                    ProcessRecord proc = uids.valueAt(j);
7437                    if (proc.userId != tr.userId) {
7438                        continue;
7439                    }
7440                    if (!proc.pkgList.containsKey(pkg)) {
7441                        continue;
7442                    }
7443                    procs.add(proc);
7444                }
7445            }
7446
7447            // Kill the running processes.
7448            for (int i=0; i<procs.size(); i++) {
7449                ProcessRecord pr = procs.get(i);
7450                if (pr == mHomeProcess) {
7451                    // Don't kill the home process along with tasks from the same package.
7452                    continue;
7453                }
7454                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7455                    killUnneededProcessLocked(pr, "remove task");
7456                } else {
7457                    pr.waitingToKill = "remove task";
7458                }
7459            }
7460        }
7461    }
7462
7463    /**
7464     * Removes the task with the specified task id.
7465     *
7466     * @param taskId Identifier of the task to be removed.
7467     * @param flags Additional operational flags.  May be 0 or
7468     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7469     * @return Returns true if the given task was found and removed.
7470     */
7471    private boolean removeTaskByIdLocked(int taskId, int flags) {
7472        TaskRecord tr = recentTaskForIdLocked(taskId);
7473        if (tr != null) {
7474            tr.removeTaskActivitiesLocked(-1, false);
7475            cleanUpRemovedTaskLocked(tr, flags);
7476            if (tr.isPersistable) {
7477                notifyTaskPersisterLocked(tr, true);
7478            }
7479            return true;
7480        }
7481        return false;
7482    }
7483
7484    @Override
7485    public boolean removeTask(int taskId, int flags) {
7486        synchronized (this) {
7487            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7488                    "removeTask()");
7489            long ident = Binder.clearCallingIdentity();
7490            try {
7491                return removeTaskByIdLocked(taskId, flags);
7492            } finally {
7493                Binder.restoreCallingIdentity(ident);
7494            }
7495        }
7496    }
7497
7498    /**
7499     * TODO: Add mController hook
7500     */
7501    @Override
7502    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7503        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7504                "moveTaskToFront()");
7505
7506        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7507        synchronized(this) {
7508            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7509                    Binder.getCallingUid(), "Task to front")) {
7510                ActivityOptions.abort(options);
7511                return;
7512            }
7513            final long origId = Binder.clearCallingIdentity();
7514            try {
7515                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7516                if (task == null) {
7517                    return;
7518                }
7519                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7520                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7521                    return;
7522                }
7523                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7524                if (prev != null && prev.isRecentsActivity()) {
7525                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7526                }
7527                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7528            } finally {
7529                Binder.restoreCallingIdentity(origId);
7530            }
7531            ActivityOptions.abort(options);
7532        }
7533    }
7534
7535    @Override
7536    public void moveTaskToBack(int taskId) {
7537        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7538                "moveTaskToBack()");
7539
7540        synchronized(this) {
7541            TaskRecord tr = recentTaskForIdLocked(taskId);
7542            if (tr != null) {
7543                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7544                ActivityStack stack = tr.stack;
7545                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7546                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7547                            Binder.getCallingUid(), "Task to back")) {
7548                        return;
7549                    }
7550                }
7551                final long origId = Binder.clearCallingIdentity();
7552                try {
7553                    stack.moveTaskToBackLocked(taskId, null);
7554                } finally {
7555                    Binder.restoreCallingIdentity(origId);
7556                }
7557            }
7558        }
7559    }
7560
7561    /**
7562     * Moves an activity, and all of the other activities within the same task, to the bottom
7563     * of the history stack.  The activity's order within the task is unchanged.
7564     *
7565     * @param token A reference to the activity we wish to move
7566     * @param nonRoot If false then this only works if the activity is the root
7567     *                of a task; if true it will work for any activity in a task.
7568     * @return Returns true if the move completed, false if not.
7569     */
7570    @Override
7571    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7572        enforceNotIsolatedCaller("moveActivityTaskToBack");
7573        synchronized(this) {
7574            final long origId = Binder.clearCallingIdentity();
7575            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7576            if (taskId >= 0) {
7577                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7578            }
7579            Binder.restoreCallingIdentity(origId);
7580        }
7581        return false;
7582    }
7583
7584    @Override
7585    public void moveTaskBackwards(int task) {
7586        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7587                "moveTaskBackwards()");
7588
7589        synchronized(this) {
7590            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7591                    Binder.getCallingUid(), "Task backwards")) {
7592                return;
7593            }
7594            final long origId = Binder.clearCallingIdentity();
7595            moveTaskBackwardsLocked(task);
7596            Binder.restoreCallingIdentity(origId);
7597        }
7598    }
7599
7600    private final void moveTaskBackwardsLocked(int task) {
7601        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7602    }
7603
7604    @Override
7605    public IBinder getHomeActivityToken() throws RemoteException {
7606        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7607                "getHomeActivityToken()");
7608        synchronized (this) {
7609            return mStackSupervisor.getHomeActivityToken();
7610        }
7611    }
7612
7613    @Override
7614    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7615            IActivityContainerCallback callback) throws RemoteException {
7616        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7617                "createActivityContainer()");
7618        synchronized (this) {
7619            if (parentActivityToken == null) {
7620                throw new IllegalArgumentException("parent token must not be null");
7621            }
7622            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7623            if (r == null) {
7624                return null;
7625            }
7626            if (callback == null) {
7627                throw new IllegalArgumentException("callback must not be null");
7628            }
7629            return mStackSupervisor.createActivityContainer(r, callback);
7630        }
7631    }
7632
7633    @Override
7634    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7635        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7636                "deleteActivityContainer()");
7637        synchronized (this) {
7638            mStackSupervisor.deleteActivityContainer(container);
7639        }
7640    }
7641
7642    @Override
7643    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7644            throws RemoteException {
7645        synchronized (this) {
7646            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7647            if (stack != null) {
7648                return stack.mActivityContainer;
7649            }
7650            return null;
7651        }
7652    }
7653
7654    @Override
7655    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7656        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7657                "moveTaskToStack()");
7658        if (stackId == HOME_STACK_ID) {
7659            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7660                    new RuntimeException("here").fillInStackTrace());
7661        }
7662        synchronized (this) {
7663            long ident = Binder.clearCallingIdentity();
7664            try {
7665                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7666                        + stackId + " toTop=" + toTop);
7667                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7668            } finally {
7669                Binder.restoreCallingIdentity(ident);
7670            }
7671        }
7672    }
7673
7674    @Override
7675    public void resizeStack(int stackBoxId, Rect bounds) {
7676        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7677                "resizeStackBox()");
7678        long ident = Binder.clearCallingIdentity();
7679        try {
7680            mWindowManager.resizeStack(stackBoxId, bounds);
7681        } finally {
7682            Binder.restoreCallingIdentity(ident);
7683        }
7684    }
7685
7686    @Override
7687    public List<StackInfo> getAllStackInfos() {
7688        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7689                "getAllStackInfos()");
7690        long ident = Binder.clearCallingIdentity();
7691        try {
7692            synchronized (this) {
7693                return mStackSupervisor.getAllStackInfosLocked();
7694            }
7695        } finally {
7696            Binder.restoreCallingIdentity(ident);
7697        }
7698    }
7699
7700    @Override
7701    public StackInfo getStackInfo(int stackId) {
7702        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7703                "getStackInfo()");
7704        long ident = Binder.clearCallingIdentity();
7705        try {
7706            synchronized (this) {
7707                return mStackSupervisor.getStackInfoLocked(stackId);
7708            }
7709        } finally {
7710            Binder.restoreCallingIdentity(ident);
7711        }
7712    }
7713
7714    @Override
7715    public boolean isInHomeStack(int taskId) {
7716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7717                "getStackInfo()");
7718        long ident = Binder.clearCallingIdentity();
7719        try {
7720            synchronized (this) {
7721                TaskRecord tr = recentTaskForIdLocked(taskId);
7722                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7723            }
7724        } finally {
7725            Binder.restoreCallingIdentity(ident);
7726        }
7727    }
7728
7729    @Override
7730    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7731        synchronized(this) {
7732            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7733        }
7734    }
7735
7736    private boolean isLockTaskAuthorized(String pkg) {
7737        final DevicePolicyManager dpm = (DevicePolicyManager)
7738                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7739        try {
7740            int uid = mContext.getPackageManager().getPackageUid(pkg,
7741                    Binder.getCallingUserHandle().getIdentifier());
7742            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7743        } catch (NameNotFoundException e) {
7744            return false;
7745        }
7746    }
7747
7748    void startLockTaskMode(TaskRecord task) {
7749        final String pkg;
7750        synchronized (this) {
7751            pkg = task.intent.getComponent().getPackageName();
7752        }
7753        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7754        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7755            final TaskRecord taskRecord = task;
7756            mHandler.post(new Runnable() {
7757                @Override
7758                public void run() {
7759                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7760                }
7761            });
7762            return;
7763        }
7764        long ident = Binder.clearCallingIdentity();
7765        try {
7766            synchronized (this) {
7767                // Since we lost lock on task, make sure it is still there.
7768                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7769                if (task != null) {
7770                    if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
7771                        throw new IllegalArgumentException("Invalid task, not in foreground");
7772                    }
7773                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7774                }
7775            }
7776        } finally {
7777            Binder.restoreCallingIdentity(ident);
7778        }
7779    }
7780
7781    @Override
7782    public void startLockTaskMode(int taskId) {
7783        final TaskRecord task;
7784        long ident = Binder.clearCallingIdentity();
7785        try {
7786            synchronized (this) {
7787                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7788            }
7789        } finally {
7790            Binder.restoreCallingIdentity(ident);
7791        }
7792        if (task != null) {
7793            startLockTaskMode(task);
7794        }
7795    }
7796
7797    @Override
7798    public void startLockTaskMode(IBinder token) {
7799        final TaskRecord task;
7800        long ident = Binder.clearCallingIdentity();
7801        try {
7802            synchronized (this) {
7803                final ActivityRecord r = ActivityRecord.forToken(token);
7804                if (r == null) {
7805                    return;
7806                }
7807                task = r.task;
7808            }
7809        } finally {
7810            Binder.restoreCallingIdentity(ident);
7811        }
7812        if (task != null) {
7813            startLockTaskMode(task);
7814        }
7815    }
7816
7817    @Override
7818    public void startLockTaskModeOnCurrent() throws RemoteException {
7819        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7820        ActivityRecord r = null;
7821        synchronized (this) {
7822            r = mStackSupervisor.topRunningActivityLocked();
7823        }
7824        startLockTaskMode(r.task);
7825    }
7826
7827    @Override
7828    public void stopLockTaskMode() {
7829        // Verify that the user matches the package of the intent for the TaskRecord
7830        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7831        // and stopLockTaskMode.
7832        final int callingUid = Binder.getCallingUid();
7833        if (callingUid != Process.SYSTEM_UID) {
7834            try {
7835                String pkg =
7836                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7837                int uid = mContext.getPackageManager().getPackageUid(pkg,
7838                        Binder.getCallingUserHandle().getIdentifier());
7839                if (uid != callingUid) {
7840                    throw new SecurityException("Invalid uid, expected " + uid);
7841                }
7842            } catch (NameNotFoundException e) {
7843                Log.d(TAG, "stopLockTaskMode " + e);
7844                return;
7845            }
7846        }
7847        long ident = Binder.clearCallingIdentity();
7848        try {
7849            Log.d(TAG, "stopLockTaskMode");
7850            // Stop lock task
7851            synchronized (this) {
7852                mStackSupervisor.setLockTaskModeLocked(null, false);
7853            }
7854        } finally {
7855            Binder.restoreCallingIdentity(ident);
7856        }
7857    }
7858
7859    @Override
7860    public void stopLockTaskModeOnCurrent() throws RemoteException {
7861        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7862        long ident = Binder.clearCallingIdentity();
7863        try {
7864            stopLockTaskMode();
7865        } finally {
7866            Binder.restoreCallingIdentity(ident);
7867        }
7868    }
7869
7870    @Override
7871    public boolean isInLockTaskMode() {
7872        synchronized (this) {
7873            return mStackSupervisor.isInLockTaskMode();
7874        }
7875    }
7876
7877    // =========================================================
7878    // CONTENT PROVIDERS
7879    // =========================================================
7880
7881    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7882        List<ProviderInfo> providers = null;
7883        try {
7884            providers = AppGlobals.getPackageManager().
7885                queryContentProviders(app.processName, app.uid,
7886                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7887        } catch (RemoteException ex) {
7888        }
7889        if (DEBUG_MU)
7890            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7891        int userId = app.userId;
7892        if (providers != null) {
7893            int N = providers.size();
7894            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7895            for (int i=0; i<N; i++) {
7896                ProviderInfo cpi =
7897                    (ProviderInfo)providers.get(i);
7898                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7899                        cpi.name, cpi.flags);
7900                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7901                    // This is a singleton provider, but a user besides the
7902                    // default user is asking to initialize a process it runs
7903                    // in...  well, no, it doesn't actually run in this process,
7904                    // it runs in the process of the default user.  Get rid of it.
7905                    providers.remove(i);
7906                    N--;
7907                    i--;
7908                    continue;
7909                }
7910
7911                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7912                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7913                if (cpr == null) {
7914                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7915                    mProviderMap.putProviderByClass(comp, cpr);
7916                }
7917                if (DEBUG_MU)
7918                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7919                app.pubProviders.put(cpi.name, cpr);
7920                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7921                    // Don't add this if it is a platform component that is marked
7922                    // to run in multiple processes, because this is actually
7923                    // part of the framework so doesn't make sense to track as a
7924                    // separate apk in the process.
7925                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7926                            mProcessStats);
7927                }
7928                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7929            }
7930        }
7931        return providers;
7932    }
7933
7934    /**
7935     * Check if {@link ProcessRecord} has a possible chance at accessing the
7936     * given {@link ProviderInfo}. Final permission checking is always done
7937     * in {@link ContentProvider}.
7938     */
7939    private final String checkContentProviderPermissionLocked(
7940            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7941        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7942        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7943        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7944        // Looking for cross-user grants before to enforce the typical cross-users permissions
7945        if (userId != UserHandle.getUserId(callingUid)) {
7946            if (perms != null) {
7947                for (GrantUri grantUri : perms.keySet()) {
7948                    if (grantUri.sourceUserId == userId) {
7949                        String authority = grantUri.uri.getAuthority();
7950                        if (authority.equals(cpi.authority)) {
7951                            return null;
7952                        }
7953                    }
7954                }
7955            }
7956        }
7957        if (checkUser) {
7958            userId = handleIncomingUser(callingPid, callingUid, userId,
7959                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7960        }
7961        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7962                cpi.applicationInfo.uid, cpi.exported)
7963                == PackageManager.PERMISSION_GRANTED) {
7964            return null;
7965        }
7966        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7967                cpi.applicationInfo.uid, cpi.exported)
7968                == PackageManager.PERMISSION_GRANTED) {
7969            return null;
7970        }
7971
7972        PathPermission[] pps = cpi.pathPermissions;
7973        if (pps != null) {
7974            int i = pps.length;
7975            while (i > 0) {
7976                i--;
7977                PathPermission pp = pps[i];
7978                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7979                        cpi.applicationInfo.uid, cpi.exported)
7980                        == PackageManager.PERMISSION_GRANTED) {
7981                    return null;
7982                }
7983                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7984                        cpi.applicationInfo.uid, cpi.exported)
7985                        == PackageManager.PERMISSION_GRANTED) {
7986                    return null;
7987                }
7988            }
7989        }
7990
7991        if (perms != null) {
7992            for (GrantUri grantUri : perms.keySet()) {
7993                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7994                    return null;
7995                }
7996            }
7997        }
7998
7999        String msg;
8000        if (!cpi.exported) {
8001            msg = "Permission Denial: opening provider " + cpi.name
8002                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8003                    + ", uid=" + callingUid + ") that is not exported from uid "
8004                    + cpi.applicationInfo.uid;
8005        } else {
8006            msg = "Permission Denial: opening provider " + cpi.name
8007                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8008                    + ", uid=" + callingUid + ") requires "
8009                    + cpi.readPermission + " or " + cpi.writePermission;
8010        }
8011        Slog.w(TAG, msg);
8012        return msg;
8013    }
8014
8015    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8016            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8017        if (r != null) {
8018            for (int i=0; i<r.conProviders.size(); i++) {
8019                ContentProviderConnection conn = r.conProviders.get(i);
8020                if (conn.provider == cpr) {
8021                    if (DEBUG_PROVIDER) Slog.v(TAG,
8022                            "Adding provider requested by "
8023                            + r.processName + " from process "
8024                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8025                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8026                    if (stable) {
8027                        conn.stableCount++;
8028                        conn.numStableIncs++;
8029                    } else {
8030                        conn.unstableCount++;
8031                        conn.numUnstableIncs++;
8032                    }
8033                    return conn;
8034                }
8035            }
8036            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8037            if (stable) {
8038                conn.stableCount = 1;
8039                conn.numStableIncs = 1;
8040            } else {
8041                conn.unstableCount = 1;
8042                conn.numUnstableIncs = 1;
8043            }
8044            cpr.connections.add(conn);
8045            r.conProviders.add(conn);
8046            return conn;
8047        }
8048        cpr.addExternalProcessHandleLocked(externalProcessToken);
8049        return null;
8050    }
8051
8052    boolean decProviderCountLocked(ContentProviderConnection conn,
8053            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8054        if (conn != null) {
8055            cpr = conn.provider;
8056            if (DEBUG_PROVIDER) Slog.v(TAG,
8057                    "Removing provider requested by "
8058                    + conn.client.processName + " from process "
8059                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8060                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8061            if (stable) {
8062                conn.stableCount--;
8063            } else {
8064                conn.unstableCount--;
8065            }
8066            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8067                cpr.connections.remove(conn);
8068                conn.client.conProviders.remove(conn);
8069                return true;
8070            }
8071            return false;
8072        }
8073        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8074        return false;
8075    }
8076
8077    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8078            String name, IBinder token, boolean stable, int userId) {
8079        ContentProviderRecord cpr;
8080        ContentProviderConnection conn = null;
8081        ProviderInfo cpi = null;
8082
8083        synchronized(this) {
8084            ProcessRecord r = null;
8085            if (caller != null) {
8086                r = getRecordForAppLocked(caller);
8087                if (r == null) {
8088                    throw new SecurityException(
8089                            "Unable to find app for caller " + caller
8090                          + " (pid=" + Binder.getCallingPid()
8091                          + ") when getting content provider " + name);
8092                }
8093            }
8094
8095            boolean checkCrossUser = true;
8096
8097            // First check if this content provider has been published...
8098            cpr = mProviderMap.getProviderByName(name, userId);
8099            // If that didn't work, check if it exists for user 0 and then
8100            // verify that it's a singleton provider before using it.
8101            if (cpr == null && userId != UserHandle.USER_OWNER) {
8102                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8103                if (cpr != null) {
8104                    cpi = cpr.info;
8105                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8106                            cpi.name, cpi.flags)
8107                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8108                        userId = UserHandle.USER_OWNER;
8109                        checkCrossUser = false;
8110                    } else {
8111                        cpr = null;
8112                        cpi = null;
8113                    }
8114                }
8115            }
8116
8117            boolean providerRunning = cpr != null;
8118            if (providerRunning) {
8119                cpi = cpr.info;
8120                String msg;
8121                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8122                        != null) {
8123                    throw new SecurityException(msg);
8124                }
8125
8126                if (r != null && cpr.canRunHere(r)) {
8127                    // This provider has been published or is in the process
8128                    // of being published...  but it is also allowed to run
8129                    // in the caller's process, so don't make a connection
8130                    // and just let the caller instantiate its own instance.
8131                    ContentProviderHolder holder = cpr.newHolder(null);
8132                    // don't give caller the provider object, it needs
8133                    // to make its own.
8134                    holder.provider = null;
8135                    return holder;
8136                }
8137
8138                final long origId = Binder.clearCallingIdentity();
8139
8140                // In this case the provider instance already exists, so we can
8141                // return it right away.
8142                conn = incProviderCountLocked(r, cpr, token, stable);
8143                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8144                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8145                        // If this is a perceptible app accessing the provider,
8146                        // make sure to count it as being accessed and thus
8147                        // back up on the LRU list.  This is good because
8148                        // content providers are often expensive to start.
8149                        updateLruProcessLocked(cpr.proc, false, null);
8150                    }
8151                }
8152
8153                if (cpr.proc != null) {
8154                    if (false) {
8155                        if (cpr.name.flattenToShortString().equals(
8156                                "com.android.providers.calendar/.CalendarProvider2")) {
8157                            Slog.v(TAG, "****************** KILLING "
8158                                + cpr.name.flattenToShortString());
8159                            Process.killProcess(cpr.proc.pid);
8160                        }
8161                    }
8162                    boolean success = updateOomAdjLocked(cpr.proc);
8163                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8164                    // NOTE: there is still a race here where a signal could be
8165                    // pending on the process even though we managed to update its
8166                    // adj level.  Not sure what to do about this, but at least
8167                    // the race is now smaller.
8168                    if (!success) {
8169                        // Uh oh...  it looks like the provider's process
8170                        // has been killed on us.  We need to wait for a new
8171                        // process to be started, and make sure its death
8172                        // doesn't kill our process.
8173                        Slog.i(TAG,
8174                                "Existing provider " + cpr.name.flattenToShortString()
8175                                + " is crashing; detaching " + r);
8176                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8177                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8178                        if (!lastRef) {
8179                            // This wasn't the last ref our process had on
8180                            // the provider...  we have now been killed, bail.
8181                            return null;
8182                        }
8183                        providerRunning = false;
8184                        conn = null;
8185                    }
8186                }
8187
8188                Binder.restoreCallingIdentity(origId);
8189            }
8190
8191            boolean singleton;
8192            if (!providerRunning) {
8193                try {
8194                    cpi = AppGlobals.getPackageManager().
8195                        resolveContentProvider(name,
8196                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8197                } catch (RemoteException ex) {
8198                }
8199                if (cpi == null) {
8200                    return null;
8201                }
8202                // If the provider is a singleton AND
8203                // (it's a call within the same user || the provider is a
8204                // privileged app)
8205                // Then allow connecting to the singleton provider
8206                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8207                        cpi.name, cpi.flags)
8208                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8209                if (singleton) {
8210                    userId = UserHandle.USER_OWNER;
8211                }
8212                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8213
8214                String msg;
8215                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8216                        != null) {
8217                    throw new SecurityException(msg);
8218                }
8219
8220                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8221                        && !cpi.processName.equals("system")) {
8222                    // If this content provider does not run in the system
8223                    // process, and the system is not yet ready to run other
8224                    // processes, then fail fast instead of hanging.
8225                    throw new IllegalArgumentException(
8226                            "Attempt to launch content provider before system ready");
8227                }
8228
8229                // Make sure that the user who owns this provider is started.  If not,
8230                // we don't want to allow it to run.
8231                if (mStartedUsers.get(userId) == null) {
8232                    Slog.w(TAG, "Unable to launch app "
8233                            + cpi.applicationInfo.packageName + "/"
8234                            + cpi.applicationInfo.uid + " for provider "
8235                            + name + ": user " + userId + " is stopped");
8236                    return null;
8237                }
8238
8239                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8240                cpr = mProviderMap.getProviderByClass(comp, userId);
8241                final boolean firstClass = cpr == null;
8242                if (firstClass) {
8243                    try {
8244                        ApplicationInfo ai =
8245                            AppGlobals.getPackageManager().
8246                                getApplicationInfo(
8247                                        cpi.applicationInfo.packageName,
8248                                        STOCK_PM_FLAGS, userId);
8249                        if (ai == null) {
8250                            Slog.w(TAG, "No package info for content provider "
8251                                    + cpi.name);
8252                            return null;
8253                        }
8254                        ai = getAppInfoForUser(ai, userId);
8255                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8256                    } catch (RemoteException ex) {
8257                        // pm is in same process, this will never happen.
8258                    }
8259                }
8260
8261                if (r != null && cpr.canRunHere(r)) {
8262                    // If this is a multiprocess provider, then just return its
8263                    // info and allow the caller to instantiate it.  Only do
8264                    // this if the provider is the same user as the caller's
8265                    // process, or can run as root (so can be in any process).
8266                    return cpr.newHolder(null);
8267                }
8268
8269                if (DEBUG_PROVIDER) {
8270                    RuntimeException e = new RuntimeException("here");
8271                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8272                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8273                }
8274
8275                // This is single process, and our app is now connecting to it.
8276                // See if we are already in the process of launching this
8277                // provider.
8278                final int N = mLaunchingProviders.size();
8279                int i;
8280                for (i=0; i<N; i++) {
8281                    if (mLaunchingProviders.get(i) == cpr) {
8282                        break;
8283                    }
8284                }
8285
8286                // If the provider is not already being launched, then get it
8287                // started.
8288                if (i >= N) {
8289                    final long origId = Binder.clearCallingIdentity();
8290
8291                    try {
8292                        // Content provider is now in use, its package can't be stopped.
8293                        try {
8294                            AppGlobals.getPackageManager().setPackageStoppedState(
8295                                    cpr.appInfo.packageName, false, userId);
8296                        } catch (RemoteException e) {
8297                        } catch (IllegalArgumentException e) {
8298                            Slog.w(TAG, "Failed trying to unstop package "
8299                                    + cpr.appInfo.packageName + ": " + e);
8300                        }
8301
8302                        // Use existing process if already started
8303                        ProcessRecord proc = getProcessRecordLocked(
8304                                cpi.processName, cpr.appInfo.uid, false);
8305                        if (proc != null && proc.thread != null) {
8306                            if (DEBUG_PROVIDER) {
8307                                Slog.d(TAG, "Installing in existing process " + proc);
8308                            }
8309                            proc.pubProviders.put(cpi.name, cpr);
8310                            try {
8311                                proc.thread.scheduleInstallProvider(cpi);
8312                            } catch (RemoteException e) {
8313                            }
8314                        } else {
8315                            proc = startProcessLocked(cpi.processName,
8316                                    cpr.appInfo, false, 0, "content provider",
8317                                    new ComponentName(cpi.applicationInfo.packageName,
8318                                            cpi.name), false, false, false);
8319                            if (proc == null) {
8320                                Slog.w(TAG, "Unable to launch app "
8321                                        + cpi.applicationInfo.packageName + "/"
8322                                        + cpi.applicationInfo.uid + " for provider "
8323                                        + name + ": process is bad");
8324                                return null;
8325                            }
8326                        }
8327                        cpr.launchingApp = proc;
8328                        mLaunchingProviders.add(cpr);
8329                    } finally {
8330                        Binder.restoreCallingIdentity(origId);
8331                    }
8332                }
8333
8334                // Make sure the provider is published (the same provider class
8335                // may be published under multiple names).
8336                if (firstClass) {
8337                    mProviderMap.putProviderByClass(comp, cpr);
8338                }
8339
8340                mProviderMap.putProviderByName(name, cpr);
8341                conn = incProviderCountLocked(r, cpr, token, stable);
8342                if (conn != null) {
8343                    conn.waiting = true;
8344                }
8345            }
8346        }
8347
8348        // Wait for the provider to be published...
8349        synchronized (cpr) {
8350            while (cpr.provider == null) {
8351                if (cpr.launchingApp == null) {
8352                    Slog.w(TAG, "Unable to launch app "
8353                            + cpi.applicationInfo.packageName + "/"
8354                            + cpi.applicationInfo.uid + " for provider "
8355                            + name + ": launching app became null");
8356                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8357                            UserHandle.getUserId(cpi.applicationInfo.uid),
8358                            cpi.applicationInfo.packageName,
8359                            cpi.applicationInfo.uid, name);
8360                    return null;
8361                }
8362                try {
8363                    if (DEBUG_MU) {
8364                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8365                                + cpr.launchingApp);
8366                    }
8367                    if (conn != null) {
8368                        conn.waiting = true;
8369                    }
8370                    cpr.wait();
8371                } catch (InterruptedException ex) {
8372                } finally {
8373                    if (conn != null) {
8374                        conn.waiting = false;
8375                    }
8376                }
8377            }
8378        }
8379        return cpr != null ? cpr.newHolder(conn) : null;
8380    }
8381
8382    @Override
8383    public final ContentProviderHolder getContentProvider(
8384            IApplicationThread caller, String name, int userId, boolean stable) {
8385        enforceNotIsolatedCaller("getContentProvider");
8386        if (caller == null) {
8387            String msg = "null IApplicationThread when getting content provider "
8388                    + name;
8389            Slog.w(TAG, msg);
8390            throw new SecurityException(msg);
8391        }
8392        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8393        // with cross-user grant.
8394        return getContentProviderImpl(caller, name, null, stable, userId);
8395    }
8396
8397    public ContentProviderHolder getContentProviderExternal(
8398            String name, int userId, IBinder token) {
8399        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8400            "Do not have permission in call getContentProviderExternal()");
8401        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8402                false, true, "getContentProvider", null);
8403        return getContentProviderExternalUnchecked(name, token, userId);
8404    }
8405
8406    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8407            IBinder token, int userId) {
8408        return getContentProviderImpl(null, name, token, true, userId);
8409    }
8410
8411    /**
8412     * Drop a content provider from a ProcessRecord's bookkeeping
8413     */
8414    public void removeContentProvider(IBinder connection, boolean stable) {
8415        enforceNotIsolatedCaller("removeContentProvider");
8416        long ident = Binder.clearCallingIdentity();
8417        try {
8418            synchronized (this) {
8419                ContentProviderConnection conn;
8420                try {
8421                    conn = (ContentProviderConnection)connection;
8422                } catch (ClassCastException e) {
8423                    String msg ="removeContentProvider: " + connection
8424                            + " not a ContentProviderConnection";
8425                    Slog.w(TAG, msg);
8426                    throw new IllegalArgumentException(msg);
8427                }
8428                if (conn == null) {
8429                    throw new NullPointerException("connection is null");
8430                }
8431                if (decProviderCountLocked(conn, null, null, stable)) {
8432                    updateOomAdjLocked();
8433                }
8434            }
8435        } finally {
8436            Binder.restoreCallingIdentity(ident);
8437        }
8438    }
8439
8440    public void removeContentProviderExternal(String name, IBinder token) {
8441        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8442            "Do not have permission in call removeContentProviderExternal()");
8443        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8444    }
8445
8446    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8447        synchronized (this) {
8448            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8449            if(cpr == null) {
8450                //remove from mProvidersByClass
8451                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8452                return;
8453            }
8454
8455            //update content provider record entry info
8456            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8457            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8458            if (localCpr.hasExternalProcessHandles()) {
8459                if (localCpr.removeExternalProcessHandleLocked(token)) {
8460                    updateOomAdjLocked();
8461                } else {
8462                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8463                            + " with no external reference for token: "
8464                            + token + ".");
8465                }
8466            } else {
8467                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8468                        + " with no external references.");
8469            }
8470        }
8471    }
8472
8473    public final void publishContentProviders(IApplicationThread caller,
8474            List<ContentProviderHolder> providers) {
8475        if (providers == null) {
8476            return;
8477        }
8478
8479        enforceNotIsolatedCaller("publishContentProviders");
8480        synchronized (this) {
8481            final ProcessRecord r = getRecordForAppLocked(caller);
8482            if (DEBUG_MU)
8483                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8484            if (r == null) {
8485                throw new SecurityException(
8486                        "Unable to find app for caller " + caller
8487                      + " (pid=" + Binder.getCallingPid()
8488                      + ") when publishing content providers");
8489            }
8490
8491            final long origId = Binder.clearCallingIdentity();
8492
8493            final int N = providers.size();
8494            for (int i=0; i<N; i++) {
8495                ContentProviderHolder src = providers.get(i);
8496                if (src == null || src.info == null || src.provider == null) {
8497                    continue;
8498                }
8499                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8500                if (DEBUG_MU)
8501                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8502                if (dst != null) {
8503                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8504                    mProviderMap.putProviderByClass(comp, dst);
8505                    String names[] = dst.info.authority.split(";");
8506                    for (int j = 0; j < names.length; j++) {
8507                        mProviderMap.putProviderByName(names[j], dst);
8508                    }
8509
8510                    int NL = mLaunchingProviders.size();
8511                    int j;
8512                    for (j=0; j<NL; j++) {
8513                        if (mLaunchingProviders.get(j) == dst) {
8514                            mLaunchingProviders.remove(j);
8515                            j--;
8516                            NL--;
8517                        }
8518                    }
8519                    synchronized (dst) {
8520                        dst.provider = src.provider;
8521                        dst.proc = r;
8522                        dst.notifyAll();
8523                    }
8524                    updateOomAdjLocked(r);
8525                }
8526            }
8527
8528            Binder.restoreCallingIdentity(origId);
8529        }
8530    }
8531
8532    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8533        ContentProviderConnection conn;
8534        try {
8535            conn = (ContentProviderConnection)connection;
8536        } catch (ClassCastException e) {
8537            String msg ="refContentProvider: " + connection
8538                    + " not a ContentProviderConnection";
8539            Slog.w(TAG, msg);
8540            throw new IllegalArgumentException(msg);
8541        }
8542        if (conn == null) {
8543            throw new NullPointerException("connection is null");
8544        }
8545
8546        synchronized (this) {
8547            if (stable > 0) {
8548                conn.numStableIncs += stable;
8549            }
8550            stable = conn.stableCount + stable;
8551            if (stable < 0) {
8552                throw new IllegalStateException("stableCount < 0: " + stable);
8553            }
8554
8555            if (unstable > 0) {
8556                conn.numUnstableIncs += unstable;
8557            }
8558            unstable = conn.unstableCount + unstable;
8559            if (unstable < 0) {
8560                throw new IllegalStateException("unstableCount < 0: " + unstable);
8561            }
8562
8563            if ((stable+unstable) <= 0) {
8564                throw new IllegalStateException("ref counts can't go to zero here: stable="
8565                        + stable + " unstable=" + unstable);
8566            }
8567            conn.stableCount = stable;
8568            conn.unstableCount = unstable;
8569            return !conn.dead;
8570        }
8571    }
8572
8573    public void unstableProviderDied(IBinder connection) {
8574        ContentProviderConnection conn;
8575        try {
8576            conn = (ContentProviderConnection)connection;
8577        } catch (ClassCastException e) {
8578            String msg ="refContentProvider: " + connection
8579                    + " not a ContentProviderConnection";
8580            Slog.w(TAG, msg);
8581            throw new IllegalArgumentException(msg);
8582        }
8583        if (conn == null) {
8584            throw new NullPointerException("connection is null");
8585        }
8586
8587        // Safely retrieve the content provider associated with the connection.
8588        IContentProvider provider;
8589        synchronized (this) {
8590            provider = conn.provider.provider;
8591        }
8592
8593        if (provider == null) {
8594            // Um, yeah, we're way ahead of you.
8595            return;
8596        }
8597
8598        // Make sure the caller is being honest with us.
8599        if (provider.asBinder().pingBinder()) {
8600            // Er, no, still looks good to us.
8601            synchronized (this) {
8602                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8603                        + " says " + conn + " died, but we don't agree");
8604                return;
8605            }
8606        }
8607
8608        // Well look at that!  It's dead!
8609        synchronized (this) {
8610            if (conn.provider.provider != provider) {
8611                // But something changed...  good enough.
8612                return;
8613            }
8614
8615            ProcessRecord proc = conn.provider.proc;
8616            if (proc == null || proc.thread == null) {
8617                // Seems like the process is already cleaned up.
8618                return;
8619            }
8620
8621            // As far as we're concerned, this is just like receiving a
8622            // death notification...  just a bit prematurely.
8623            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8624                    + ") early provider death");
8625            final long ident = Binder.clearCallingIdentity();
8626            try {
8627                appDiedLocked(proc, proc.pid, proc.thread);
8628            } finally {
8629                Binder.restoreCallingIdentity(ident);
8630            }
8631        }
8632    }
8633
8634    @Override
8635    public void appNotRespondingViaProvider(IBinder connection) {
8636        enforceCallingPermission(
8637                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8638
8639        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8640        if (conn == null) {
8641            Slog.w(TAG, "ContentProviderConnection is null");
8642            return;
8643        }
8644
8645        final ProcessRecord host = conn.provider.proc;
8646        if (host == null) {
8647            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8648            return;
8649        }
8650
8651        final long token = Binder.clearCallingIdentity();
8652        try {
8653            appNotResponding(host, null, null, false, "ContentProvider not responding");
8654        } finally {
8655            Binder.restoreCallingIdentity(token);
8656        }
8657    }
8658
8659    public final void installSystemProviders() {
8660        List<ProviderInfo> providers;
8661        synchronized (this) {
8662            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8663            providers = generateApplicationProvidersLocked(app);
8664            if (providers != null) {
8665                for (int i=providers.size()-1; i>=0; i--) {
8666                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8667                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8668                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8669                                + ": not system .apk");
8670                        providers.remove(i);
8671                    }
8672                }
8673            }
8674        }
8675        if (providers != null) {
8676            mSystemThread.installSystemProviders(providers);
8677        }
8678
8679        mCoreSettingsObserver = new CoreSettingsObserver(this);
8680
8681        mUsageStatsService.monitorPackages();
8682    }
8683
8684    /**
8685     * Allows app to retrieve the MIME type of a URI without having permission
8686     * to access its content provider.
8687     *
8688     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8689     *
8690     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8691     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8692     */
8693    public String getProviderMimeType(Uri uri, int userId) {
8694        enforceNotIsolatedCaller("getProviderMimeType");
8695        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8696                userId, false, true, "getProviderMimeType", null);
8697        final String name = uri.getAuthority();
8698        final long ident = Binder.clearCallingIdentity();
8699        ContentProviderHolder holder = null;
8700
8701        try {
8702            holder = getContentProviderExternalUnchecked(name, null, userId);
8703            if (holder != null) {
8704                return holder.provider.getType(uri);
8705            }
8706        } catch (RemoteException e) {
8707            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8708            return null;
8709        } finally {
8710            if (holder != null) {
8711                removeContentProviderExternalUnchecked(name, null, userId);
8712            }
8713            Binder.restoreCallingIdentity(ident);
8714        }
8715
8716        return null;
8717    }
8718
8719    // =========================================================
8720    // GLOBAL MANAGEMENT
8721    // =========================================================
8722
8723    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8724            boolean isolated) {
8725        String proc = customProcess != null ? customProcess : info.processName;
8726        BatteryStatsImpl.Uid.Proc ps = null;
8727        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8728        int uid = info.uid;
8729        if (isolated) {
8730            int userId = UserHandle.getUserId(uid);
8731            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8732            while (true) {
8733                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8734                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8735                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8736                }
8737                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8738                mNextIsolatedProcessUid++;
8739                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8740                    // No process for this uid, use it.
8741                    break;
8742                }
8743                stepsLeft--;
8744                if (stepsLeft <= 0) {
8745                    return null;
8746                }
8747            }
8748        }
8749        return new ProcessRecord(stats, info, proc, uid);
8750    }
8751
8752    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8753            String abiOverride) {
8754        ProcessRecord app;
8755        if (!isolated) {
8756            app = getProcessRecordLocked(info.processName, info.uid, true);
8757        } else {
8758            app = null;
8759        }
8760
8761        if (app == null) {
8762            app = newProcessRecordLocked(info, null, isolated);
8763            mProcessNames.put(info.processName, app.uid, app);
8764            if (isolated) {
8765                mIsolatedProcesses.put(app.uid, app);
8766            }
8767            updateLruProcessLocked(app, false, null);
8768            updateOomAdjLocked();
8769        }
8770
8771        // This package really, really can not be stopped.
8772        try {
8773            AppGlobals.getPackageManager().setPackageStoppedState(
8774                    info.packageName, false, UserHandle.getUserId(app.uid));
8775        } catch (RemoteException e) {
8776        } catch (IllegalArgumentException e) {
8777            Slog.w(TAG, "Failed trying to unstop package "
8778                    + info.packageName + ": " + e);
8779        }
8780
8781        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8782                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8783            app.persistent = true;
8784            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8785        }
8786        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8787            mPersistentStartingProcesses.add(app);
8788            startProcessLocked(app, "added application", app.processName,
8789                    abiOverride);
8790        }
8791
8792        return app;
8793    }
8794
8795    public void unhandledBack() {
8796        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8797                "unhandledBack()");
8798
8799        synchronized(this) {
8800            final long origId = Binder.clearCallingIdentity();
8801            try {
8802                getFocusedStack().unhandledBackLocked();
8803            } finally {
8804                Binder.restoreCallingIdentity(origId);
8805            }
8806        }
8807    }
8808
8809    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8810        enforceNotIsolatedCaller("openContentUri");
8811        final int userId = UserHandle.getCallingUserId();
8812        String name = uri.getAuthority();
8813        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8814        ParcelFileDescriptor pfd = null;
8815        if (cph != null) {
8816            // We record the binder invoker's uid in thread-local storage before
8817            // going to the content provider to open the file.  Later, in the code
8818            // that handles all permissions checks, we look for this uid and use
8819            // that rather than the Activity Manager's own uid.  The effect is that
8820            // we do the check against the caller's permissions even though it looks
8821            // to the content provider like the Activity Manager itself is making
8822            // the request.
8823            sCallerIdentity.set(new Identity(
8824                    Binder.getCallingPid(), Binder.getCallingUid()));
8825            try {
8826                pfd = cph.provider.openFile(null, uri, "r", null);
8827            } catch (FileNotFoundException e) {
8828                // do nothing; pfd will be returned null
8829            } finally {
8830                // Ensure that whatever happens, we clean up the identity state
8831                sCallerIdentity.remove();
8832            }
8833
8834            // We've got the fd now, so we're done with the provider.
8835            removeContentProviderExternalUnchecked(name, null, userId);
8836        } else {
8837            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8838        }
8839        return pfd;
8840    }
8841
8842    // Actually is sleeping or shutting down or whatever else in the future
8843    // is an inactive state.
8844    public boolean isSleepingOrShuttingDown() {
8845        return mSleeping || mShuttingDown;
8846    }
8847
8848    public boolean isSleeping() {
8849        return mSleeping;
8850    }
8851
8852    void goingToSleep() {
8853        synchronized(this) {
8854            mWentToSleep = true;
8855            updateEventDispatchingLocked();
8856            goToSleepIfNeededLocked();
8857        }
8858    }
8859
8860    void finishRunningVoiceLocked() {
8861        if (mRunningVoice) {
8862            mRunningVoice = false;
8863            goToSleepIfNeededLocked();
8864        }
8865    }
8866
8867    void goToSleepIfNeededLocked() {
8868        if (mWentToSleep && !mRunningVoice) {
8869            if (!mSleeping) {
8870                mSleeping = true;
8871                mStackSupervisor.goingToSleepLocked();
8872
8873                // Initialize the wake times of all processes.
8874                checkExcessivePowerUsageLocked(false);
8875                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8876                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8877                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8878            }
8879        }
8880    }
8881
8882    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8883        mTaskPersister.notify(task, flush);
8884    }
8885
8886    @Override
8887    public boolean shutdown(int timeout) {
8888        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8889                != PackageManager.PERMISSION_GRANTED) {
8890            throw new SecurityException("Requires permission "
8891                    + android.Manifest.permission.SHUTDOWN);
8892        }
8893
8894        boolean timedout = false;
8895
8896        synchronized(this) {
8897            mShuttingDown = true;
8898            updateEventDispatchingLocked();
8899            timedout = mStackSupervisor.shutdownLocked(timeout);
8900        }
8901
8902        mAppOpsService.shutdown();
8903        mUsageStatsService.shutdown();
8904        mBatteryStatsService.shutdown();
8905        synchronized (this) {
8906            mProcessStats.shutdownLocked();
8907        }
8908        notifyTaskPersisterLocked(null, true);
8909
8910        return timedout;
8911    }
8912
8913    public final void activitySlept(IBinder token) {
8914        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8915
8916        final long origId = Binder.clearCallingIdentity();
8917
8918        synchronized (this) {
8919            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8920            if (r != null) {
8921                mStackSupervisor.activitySleptLocked(r);
8922            }
8923        }
8924
8925        Binder.restoreCallingIdentity(origId);
8926    }
8927
8928    void logLockScreen(String msg) {
8929        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8930                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8931                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8932                mStackSupervisor.mDismissKeyguardOnNextActivity);
8933    }
8934
8935    private void comeOutOfSleepIfNeededLocked() {
8936        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8937            if (mSleeping) {
8938                mSleeping = false;
8939                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8940            }
8941        }
8942    }
8943
8944    void wakingUp() {
8945        synchronized(this) {
8946            mWentToSleep = false;
8947            updateEventDispatchingLocked();
8948            comeOutOfSleepIfNeededLocked();
8949        }
8950    }
8951
8952    void startRunningVoiceLocked() {
8953        if (!mRunningVoice) {
8954            mRunningVoice = true;
8955            comeOutOfSleepIfNeededLocked();
8956        }
8957    }
8958
8959    private void updateEventDispatchingLocked() {
8960        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8961    }
8962
8963    public void setLockScreenShown(boolean shown) {
8964        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8965                != PackageManager.PERMISSION_GRANTED) {
8966            throw new SecurityException("Requires permission "
8967                    + android.Manifest.permission.DEVICE_POWER);
8968        }
8969
8970        synchronized(this) {
8971            long ident = Binder.clearCallingIdentity();
8972            try {
8973                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8974                mLockScreenShown = shown;
8975                comeOutOfSleepIfNeededLocked();
8976            } finally {
8977                Binder.restoreCallingIdentity(ident);
8978            }
8979        }
8980    }
8981
8982    public void stopAppSwitches() {
8983        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8984                != PackageManager.PERMISSION_GRANTED) {
8985            throw new SecurityException("Requires permission "
8986                    + android.Manifest.permission.STOP_APP_SWITCHES);
8987        }
8988
8989        synchronized(this) {
8990            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8991                    + APP_SWITCH_DELAY_TIME;
8992            mDidAppSwitch = false;
8993            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8994            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8995            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8996        }
8997    }
8998
8999    public void resumeAppSwitches() {
9000        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9001                != PackageManager.PERMISSION_GRANTED) {
9002            throw new SecurityException("Requires permission "
9003                    + android.Manifest.permission.STOP_APP_SWITCHES);
9004        }
9005
9006        synchronized(this) {
9007            // Note that we don't execute any pending app switches... we will
9008            // let those wait until either the timeout, or the next start
9009            // activity request.
9010            mAppSwitchesAllowedTime = 0;
9011        }
9012    }
9013
9014    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9015            String name) {
9016        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9017            return true;
9018        }
9019
9020        final int perm = checkComponentPermission(
9021                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9022                callingUid, -1, true);
9023        if (perm == PackageManager.PERMISSION_GRANTED) {
9024            return true;
9025        }
9026
9027        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9028        return false;
9029    }
9030
9031    public void setDebugApp(String packageName, boolean waitForDebugger,
9032            boolean persistent) {
9033        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9034                "setDebugApp()");
9035
9036        long ident = Binder.clearCallingIdentity();
9037        try {
9038            // Note that this is not really thread safe if there are multiple
9039            // callers into it at the same time, but that's not a situation we
9040            // care about.
9041            if (persistent) {
9042                final ContentResolver resolver = mContext.getContentResolver();
9043                Settings.Global.putString(
9044                    resolver, Settings.Global.DEBUG_APP,
9045                    packageName);
9046                Settings.Global.putInt(
9047                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9048                    waitForDebugger ? 1 : 0);
9049            }
9050
9051            synchronized (this) {
9052                if (!persistent) {
9053                    mOrigDebugApp = mDebugApp;
9054                    mOrigWaitForDebugger = mWaitForDebugger;
9055                }
9056                mDebugApp = packageName;
9057                mWaitForDebugger = waitForDebugger;
9058                mDebugTransient = !persistent;
9059                if (packageName != null) {
9060                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9061                            false, UserHandle.USER_ALL, "set debug app");
9062                }
9063            }
9064        } finally {
9065            Binder.restoreCallingIdentity(ident);
9066        }
9067    }
9068
9069    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9070        synchronized (this) {
9071            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9072            if (!isDebuggable) {
9073                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9074                    throw new SecurityException("Process not debuggable: " + app.packageName);
9075                }
9076            }
9077
9078            mOpenGlTraceApp = processName;
9079        }
9080    }
9081
9082    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9083            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9084        synchronized (this) {
9085            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9086            if (!isDebuggable) {
9087                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9088                    throw new SecurityException("Process not debuggable: " + app.packageName);
9089                }
9090            }
9091            mProfileApp = processName;
9092            mProfileFile = profileFile;
9093            if (mProfileFd != null) {
9094                try {
9095                    mProfileFd.close();
9096                } catch (IOException e) {
9097                }
9098                mProfileFd = null;
9099            }
9100            mProfileFd = profileFd;
9101            mProfileType = 0;
9102            mAutoStopProfiler = autoStopProfiler;
9103        }
9104    }
9105
9106    @Override
9107    public void setAlwaysFinish(boolean enabled) {
9108        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9109                "setAlwaysFinish()");
9110
9111        Settings.Global.putInt(
9112                mContext.getContentResolver(),
9113                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9114
9115        synchronized (this) {
9116            mAlwaysFinishActivities = enabled;
9117        }
9118    }
9119
9120    @Override
9121    public void setActivityController(IActivityController controller) {
9122        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9123                "setActivityController()");
9124        synchronized (this) {
9125            mController = controller;
9126            Watchdog.getInstance().setActivityController(controller);
9127        }
9128    }
9129
9130    @Override
9131    public void setUserIsMonkey(boolean userIsMonkey) {
9132        synchronized (this) {
9133            synchronized (mPidsSelfLocked) {
9134                final int callingPid = Binder.getCallingPid();
9135                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9136                if (precessRecord == null) {
9137                    throw new SecurityException("Unknown process: " + callingPid);
9138                }
9139                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9140                    throw new SecurityException("Only an instrumentation process "
9141                            + "with a UiAutomation can call setUserIsMonkey");
9142                }
9143            }
9144            mUserIsMonkey = userIsMonkey;
9145        }
9146    }
9147
9148    @Override
9149    public boolean isUserAMonkey() {
9150        synchronized (this) {
9151            // If there is a controller also implies the user is a monkey.
9152            return (mUserIsMonkey || mController != null);
9153        }
9154    }
9155
9156    public void requestBugReport() {
9157        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9158        SystemProperties.set("ctl.start", "bugreport");
9159    }
9160
9161    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9162        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9163    }
9164
9165    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9166        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9167            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9168        }
9169        return KEY_DISPATCHING_TIMEOUT;
9170    }
9171
9172    @Override
9173    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9174        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9175                != PackageManager.PERMISSION_GRANTED) {
9176            throw new SecurityException("Requires permission "
9177                    + android.Manifest.permission.FILTER_EVENTS);
9178        }
9179        ProcessRecord proc;
9180        long timeout;
9181        synchronized (this) {
9182            synchronized (mPidsSelfLocked) {
9183                proc = mPidsSelfLocked.get(pid);
9184            }
9185            timeout = getInputDispatchingTimeoutLocked(proc);
9186        }
9187
9188        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9189            return -1;
9190        }
9191
9192        return timeout;
9193    }
9194
9195    /**
9196     * Handle input dispatching timeouts.
9197     * Returns whether input dispatching should be aborted or not.
9198     */
9199    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9200            final ActivityRecord activity, final ActivityRecord parent,
9201            final boolean aboveSystem, String reason) {
9202        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9203                != PackageManager.PERMISSION_GRANTED) {
9204            throw new SecurityException("Requires permission "
9205                    + android.Manifest.permission.FILTER_EVENTS);
9206        }
9207
9208        final String annotation;
9209        if (reason == null) {
9210            annotation = "Input dispatching timed out";
9211        } else {
9212            annotation = "Input dispatching timed out (" + reason + ")";
9213        }
9214
9215        if (proc != null) {
9216            synchronized (this) {
9217                if (proc.debugging) {
9218                    return false;
9219                }
9220
9221                if (mDidDexOpt) {
9222                    // Give more time since we were dexopting.
9223                    mDidDexOpt = false;
9224                    return false;
9225                }
9226
9227                if (proc.instrumentationClass != null) {
9228                    Bundle info = new Bundle();
9229                    info.putString("shortMsg", "keyDispatchingTimedOut");
9230                    info.putString("longMsg", annotation);
9231                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9232                    return true;
9233                }
9234            }
9235            mHandler.post(new Runnable() {
9236                @Override
9237                public void run() {
9238                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9239                }
9240            });
9241        }
9242
9243        return true;
9244    }
9245
9246    public Bundle getAssistContextExtras(int requestType) {
9247        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9248                "getAssistContextExtras()");
9249        PendingAssistExtras pae;
9250        Bundle extras = new Bundle();
9251        synchronized (this) {
9252            ActivityRecord activity = getFocusedStack().mResumedActivity;
9253            if (activity == null) {
9254                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9255                return null;
9256            }
9257            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9258            if (activity.app == null || activity.app.thread == null) {
9259                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9260                return extras;
9261            }
9262            if (activity.app.pid == Binder.getCallingPid()) {
9263                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9264                return extras;
9265            }
9266            pae = new PendingAssistExtras(activity);
9267            try {
9268                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9269                        requestType);
9270                mPendingAssistExtras.add(pae);
9271                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9272            } catch (RemoteException e) {
9273                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9274                return extras;
9275            }
9276        }
9277        synchronized (pae) {
9278            while (!pae.haveResult) {
9279                try {
9280                    pae.wait();
9281                } catch (InterruptedException e) {
9282                }
9283            }
9284            if (pae.result != null) {
9285                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9286            }
9287        }
9288        synchronized (this) {
9289            mPendingAssistExtras.remove(pae);
9290            mHandler.removeCallbacks(pae);
9291        }
9292        return extras;
9293    }
9294
9295    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9296        PendingAssistExtras pae = (PendingAssistExtras)token;
9297        synchronized (pae) {
9298            pae.result = extras;
9299            pae.haveResult = true;
9300            pae.notifyAll();
9301        }
9302    }
9303
9304    public void registerProcessObserver(IProcessObserver observer) {
9305        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9306                "registerProcessObserver()");
9307        synchronized (this) {
9308            mProcessObservers.register(observer);
9309        }
9310    }
9311
9312    @Override
9313    public void unregisterProcessObserver(IProcessObserver observer) {
9314        synchronized (this) {
9315            mProcessObservers.unregister(observer);
9316        }
9317    }
9318
9319    @Override
9320    public boolean convertFromTranslucent(IBinder token) {
9321        final long origId = Binder.clearCallingIdentity();
9322        try {
9323            synchronized (this) {
9324                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9325                if (r == null) {
9326                    return false;
9327                }
9328                if (r.changeWindowTranslucency(true)) {
9329                    mWindowManager.setAppFullscreen(token, true);
9330                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9331                    return true;
9332                }
9333                return false;
9334            }
9335        } finally {
9336            Binder.restoreCallingIdentity(origId);
9337        }
9338    }
9339
9340    @Override
9341    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9342        final long origId = Binder.clearCallingIdentity();
9343        try {
9344            synchronized (this) {
9345                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9346                if (r == null) {
9347                    return false;
9348                }
9349                if (r.changeWindowTranslucency(false)) {
9350                    r.task.stack.convertToTranslucent(r, options);
9351                    mWindowManager.setAppFullscreen(token, false);
9352                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9353                    return true;
9354                }
9355                return false;
9356            }
9357        } finally {
9358            Binder.restoreCallingIdentity(origId);
9359        }
9360    }
9361
9362    @Override
9363    public ActivityOptions getActivityOptions(IBinder token) {
9364        final long origId = Binder.clearCallingIdentity();
9365        try {
9366            synchronized (this) {
9367                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9368                if (r != null) {
9369                    final ActivityOptions activityOptions = r.pendingOptions;
9370                    r.pendingOptions = null;
9371                    return activityOptions;
9372                }
9373                return null;
9374            }
9375        } finally {
9376            Binder.restoreCallingIdentity(origId);
9377        }
9378    }
9379
9380    @Override
9381    public void setImmersive(IBinder token, boolean immersive) {
9382        synchronized(this) {
9383            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9384            if (r == null) {
9385                throw new IllegalArgumentException();
9386            }
9387            r.immersive = immersive;
9388
9389            // update associated state if we're frontmost
9390            if (r == mFocusedActivity) {
9391                if (DEBUG_IMMERSIVE) {
9392                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9393                }
9394                applyUpdateLockStateLocked(r);
9395            }
9396        }
9397    }
9398
9399    @Override
9400    public boolean isImmersive(IBinder token) {
9401        synchronized (this) {
9402            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9403            if (r == null) {
9404                throw new IllegalArgumentException();
9405            }
9406            return r.immersive;
9407        }
9408    }
9409
9410    public boolean isTopActivityImmersive() {
9411        enforceNotIsolatedCaller("startActivity");
9412        synchronized (this) {
9413            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9414            return (r != null) ? r.immersive : false;
9415        }
9416    }
9417
9418    public final void enterSafeMode() {
9419        synchronized(this) {
9420            // It only makes sense to do this before the system is ready
9421            // and started launching other packages.
9422            if (!mSystemReady) {
9423                try {
9424                    AppGlobals.getPackageManager().enterSafeMode();
9425                } catch (RemoteException e) {
9426                }
9427            }
9428
9429            mSafeMode = true;
9430        }
9431    }
9432
9433    public final void showSafeModeOverlay() {
9434        View v = LayoutInflater.from(mContext).inflate(
9435                com.android.internal.R.layout.safe_mode, null);
9436        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9437        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9438        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9439        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9440        lp.gravity = Gravity.BOTTOM | Gravity.START;
9441        lp.format = v.getBackground().getOpacity();
9442        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9443                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9444        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9445        ((WindowManager)mContext.getSystemService(
9446                Context.WINDOW_SERVICE)).addView(v, lp);
9447    }
9448
9449    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9450        if (!(sender instanceof PendingIntentRecord)) {
9451            return;
9452        }
9453        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9454        synchronized (stats) {
9455            if (mBatteryStatsService.isOnBattery()) {
9456                mBatteryStatsService.enforceCallingPermission();
9457                PendingIntentRecord rec = (PendingIntentRecord)sender;
9458                int MY_UID = Binder.getCallingUid();
9459                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9460                BatteryStatsImpl.Uid.Pkg pkg =
9461                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9462                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9463                pkg.incWakeupsLocked();
9464            }
9465        }
9466    }
9467
9468    public boolean killPids(int[] pids, String pReason, boolean secure) {
9469        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9470            throw new SecurityException("killPids only available to the system");
9471        }
9472        String reason = (pReason == null) ? "Unknown" : pReason;
9473        // XXX Note: don't acquire main activity lock here, because the window
9474        // manager calls in with its locks held.
9475
9476        boolean killed = false;
9477        synchronized (mPidsSelfLocked) {
9478            int[] types = new int[pids.length];
9479            int worstType = 0;
9480            for (int i=0; i<pids.length; i++) {
9481                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9482                if (proc != null) {
9483                    int type = proc.setAdj;
9484                    types[i] = type;
9485                    if (type > worstType) {
9486                        worstType = type;
9487                    }
9488                }
9489            }
9490
9491            // If the worst oom_adj is somewhere in the cached proc LRU range,
9492            // then constrain it so we will kill all cached procs.
9493            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9494                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9495                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9496            }
9497
9498            // If this is not a secure call, don't let it kill processes that
9499            // are important.
9500            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9501                worstType = ProcessList.SERVICE_ADJ;
9502            }
9503
9504            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9505            for (int i=0; i<pids.length; i++) {
9506                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9507                if (proc == null) {
9508                    continue;
9509                }
9510                int adj = proc.setAdj;
9511                if (adj >= worstType && !proc.killedByAm) {
9512                    killUnneededProcessLocked(proc, reason);
9513                    killed = true;
9514                }
9515            }
9516        }
9517        return killed;
9518    }
9519
9520    @Override
9521    public void killUid(int uid, String reason) {
9522        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9523            throw new SecurityException("killUid only available to the system");
9524        }
9525        synchronized (this) {
9526            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9527                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9528                    reason != null ? reason : "kill uid");
9529        }
9530    }
9531
9532    @Override
9533    public boolean killProcessesBelowForeground(String reason) {
9534        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9535            throw new SecurityException("killProcessesBelowForeground() only available to system");
9536        }
9537
9538        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9539    }
9540
9541    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9542        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9543            throw new SecurityException("killProcessesBelowAdj() only available to system");
9544        }
9545
9546        boolean killed = false;
9547        synchronized (mPidsSelfLocked) {
9548            final int size = mPidsSelfLocked.size();
9549            for (int i = 0; i < size; i++) {
9550                final int pid = mPidsSelfLocked.keyAt(i);
9551                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9552                if (proc == null) continue;
9553
9554                final int adj = proc.setAdj;
9555                if (adj > belowAdj && !proc.killedByAm) {
9556                    killUnneededProcessLocked(proc, reason);
9557                    killed = true;
9558                }
9559            }
9560        }
9561        return killed;
9562    }
9563
9564    @Override
9565    public void hang(final IBinder who, boolean allowRestart) {
9566        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9567                != PackageManager.PERMISSION_GRANTED) {
9568            throw new SecurityException("Requires permission "
9569                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9570        }
9571
9572        final IBinder.DeathRecipient death = new DeathRecipient() {
9573            @Override
9574            public void binderDied() {
9575                synchronized (this) {
9576                    notifyAll();
9577                }
9578            }
9579        };
9580
9581        try {
9582            who.linkToDeath(death, 0);
9583        } catch (RemoteException e) {
9584            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9585            return;
9586        }
9587
9588        synchronized (this) {
9589            Watchdog.getInstance().setAllowRestart(allowRestart);
9590            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9591            synchronized (death) {
9592                while (who.isBinderAlive()) {
9593                    try {
9594                        death.wait();
9595                    } catch (InterruptedException e) {
9596                    }
9597                }
9598            }
9599            Watchdog.getInstance().setAllowRestart(true);
9600        }
9601    }
9602
9603    @Override
9604    public void restart() {
9605        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9606                != PackageManager.PERMISSION_GRANTED) {
9607            throw new SecurityException("Requires permission "
9608                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9609        }
9610
9611        Log.i(TAG, "Sending shutdown broadcast...");
9612
9613        BroadcastReceiver br = new BroadcastReceiver() {
9614            @Override public void onReceive(Context context, Intent intent) {
9615                // Now the broadcast is done, finish up the low-level shutdown.
9616                Log.i(TAG, "Shutting down activity manager...");
9617                shutdown(10000);
9618                Log.i(TAG, "Shutdown complete, restarting!");
9619                Process.killProcess(Process.myPid());
9620                System.exit(10);
9621            }
9622        };
9623
9624        // First send the high-level shut down broadcast.
9625        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9626        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9627        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9628        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9629        mContext.sendOrderedBroadcastAsUser(intent,
9630                UserHandle.ALL, null, br, mHandler, 0, null, null);
9631        */
9632        br.onReceive(mContext, intent);
9633    }
9634
9635    private long getLowRamTimeSinceIdle(long now) {
9636        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9637    }
9638
9639    @Override
9640    public void performIdleMaintenance() {
9641        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9642                != PackageManager.PERMISSION_GRANTED) {
9643            throw new SecurityException("Requires permission "
9644                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9645        }
9646
9647        synchronized (this) {
9648            final long now = SystemClock.uptimeMillis();
9649            final long timeSinceLastIdle = now - mLastIdleTime;
9650            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9651            mLastIdleTime = now;
9652            mLowRamTimeSinceLastIdle = 0;
9653            if (mLowRamStartTime != 0) {
9654                mLowRamStartTime = now;
9655            }
9656
9657            StringBuilder sb = new StringBuilder(128);
9658            sb.append("Idle maintenance over ");
9659            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9660            sb.append(" low RAM for ");
9661            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9662            Slog.i(TAG, sb.toString());
9663
9664            // If at least 1/3 of our time since the last idle period has been spent
9665            // with RAM low, then we want to kill processes.
9666            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9667
9668            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9669                ProcessRecord proc = mLruProcesses.get(i);
9670                if (proc.notCachedSinceIdle) {
9671                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9672                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9673                        if (doKilling && proc.initialIdlePss != 0
9674                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9675                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9676                                    + " from " + proc.initialIdlePss + ")");
9677                        }
9678                    }
9679                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9680                    proc.notCachedSinceIdle = true;
9681                    proc.initialIdlePss = 0;
9682                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9683                            isSleeping(), now);
9684                }
9685            }
9686
9687            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9688            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9689        }
9690    }
9691
9692    private void retrieveSettings() {
9693        final ContentResolver resolver = mContext.getContentResolver();
9694        String debugApp = Settings.Global.getString(
9695            resolver, Settings.Global.DEBUG_APP);
9696        boolean waitForDebugger = Settings.Global.getInt(
9697            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9698        boolean alwaysFinishActivities = Settings.Global.getInt(
9699            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9700        boolean forceRtl = Settings.Global.getInt(
9701                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9702        // Transfer any global setting for forcing RTL layout, into a System Property
9703        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9704
9705        Configuration configuration = new Configuration();
9706        Settings.System.getConfiguration(resolver, configuration);
9707        if (forceRtl) {
9708            // This will take care of setting the correct layout direction flags
9709            configuration.setLayoutDirection(configuration.locale);
9710        }
9711
9712        synchronized (this) {
9713            mDebugApp = mOrigDebugApp = debugApp;
9714            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9715            mAlwaysFinishActivities = alwaysFinishActivities;
9716            // This happens before any activities are started, so we can
9717            // change mConfiguration in-place.
9718            updateConfigurationLocked(configuration, null, false, true);
9719            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9720        }
9721    }
9722
9723    public boolean testIsSystemReady() {
9724        // no need to synchronize(this) just to read & return the value
9725        return mSystemReady;
9726    }
9727
9728    private static File getCalledPreBootReceiversFile() {
9729        File dataDir = Environment.getDataDirectory();
9730        File systemDir = new File(dataDir, "system");
9731        File fname = new File(systemDir, "called_pre_boots.dat");
9732        return fname;
9733    }
9734
9735    static final int LAST_DONE_VERSION = 10000;
9736
9737    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9738        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9739        File file = getCalledPreBootReceiversFile();
9740        FileInputStream fis = null;
9741        try {
9742            fis = new FileInputStream(file);
9743            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9744            int fvers = dis.readInt();
9745            if (fvers == LAST_DONE_VERSION) {
9746                String vers = dis.readUTF();
9747                String codename = dis.readUTF();
9748                String build = dis.readUTF();
9749                if (android.os.Build.VERSION.RELEASE.equals(vers)
9750                        && android.os.Build.VERSION.CODENAME.equals(codename)
9751                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9752                    int num = dis.readInt();
9753                    while (num > 0) {
9754                        num--;
9755                        String pkg = dis.readUTF();
9756                        String cls = dis.readUTF();
9757                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9758                    }
9759                }
9760            }
9761        } catch (FileNotFoundException e) {
9762        } catch (IOException e) {
9763            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9764        } finally {
9765            if (fis != null) {
9766                try {
9767                    fis.close();
9768                } catch (IOException e) {
9769                }
9770            }
9771        }
9772        return lastDoneReceivers;
9773    }
9774
9775    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9776        File file = getCalledPreBootReceiversFile();
9777        FileOutputStream fos = null;
9778        DataOutputStream dos = null;
9779        try {
9780            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9781            fos = new FileOutputStream(file);
9782            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9783            dos.writeInt(LAST_DONE_VERSION);
9784            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9785            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9786            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9787            dos.writeInt(list.size());
9788            for (int i=0; i<list.size(); i++) {
9789                dos.writeUTF(list.get(i).getPackageName());
9790                dos.writeUTF(list.get(i).getClassName());
9791            }
9792        } catch (IOException e) {
9793            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9794            file.delete();
9795        } finally {
9796            FileUtils.sync(fos);
9797            if (dos != null) {
9798                try {
9799                    dos.close();
9800                } catch (IOException e) {
9801                    // TODO Auto-generated catch block
9802                    e.printStackTrace();
9803                }
9804            }
9805        }
9806    }
9807
9808    public void systemReady(final Runnable goingCallback) {
9809        synchronized(this) {
9810            if (mSystemReady) {
9811                if (goingCallback != null) goingCallback.run();
9812                return;
9813            }
9814
9815            if (mRecentTasks == null) {
9816                mRecentTasks = mTaskPersister.restoreTasksLocked();
9817                if (!mRecentTasks.isEmpty()) {
9818                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9819                }
9820                mTaskPersister.startPersisting();
9821            }
9822
9823            // Check to see if there are any update receivers to run.
9824            if (!mDidUpdate) {
9825                if (mWaitingUpdate) {
9826                    return;
9827                }
9828                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9829                List<ResolveInfo> ris = null;
9830                try {
9831                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9832                            intent, null, 0, 0);
9833                } catch (RemoteException e) {
9834                }
9835                if (ris != null) {
9836                    for (int i=ris.size()-1; i>=0; i--) {
9837                        if ((ris.get(i).activityInfo.applicationInfo.flags
9838                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9839                            ris.remove(i);
9840                        }
9841                    }
9842                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9843
9844                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9845
9846                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9847                    for (int i=0; i<ris.size(); i++) {
9848                        ActivityInfo ai = ris.get(i).activityInfo;
9849                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9850                        if (lastDoneReceivers.contains(comp)) {
9851                            // We already did the pre boot receiver for this app with the current
9852                            // platform version, so don't do it again...
9853                            ris.remove(i);
9854                            i--;
9855                            // ...however, do keep it as one that has been done, so we don't
9856                            // forget about it when rewriting the file of last done receivers.
9857                            doneReceivers.add(comp);
9858                        }
9859                    }
9860
9861                    final int[] users = getUsersLocked();
9862                    for (int i=0; i<ris.size(); i++) {
9863                        ActivityInfo ai = ris.get(i).activityInfo;
9864                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9865                        doneReceivers.add(comp);
9866                        intent.setComponent(comp);
9867                        for (int j=0; j<users.length; j++) {
9868                            IIntentReceiver finisher = null;
9869                            if (i == ris.size()-1 && j == users.length-1) {
9870                                finisher = new IIntentReceiver.Stub() {
9871                                    public void performReceive(Intent intent, int resultCode,
9872                                            String data, Bundle extras, boolean ordered,
9873                                            boolean sticky, int sendingUser) {
9874                                        // The raw IIntentReceiver interface is called
9875                                        // with the AM lock held, so redispatch to
9876                                        // execute our code without the lock.
9877                                        mHandler.post(new Runnable() {
9878                                            public void run() {
9879                                                synchronized (ActivityManagerService.this) {
9880                                                    mDidUpdate = true;
9881                                                }
9882                                                writeLastDonePreBootReceivers(doneReceivers);
9883                                                showBootMessage(mContext.getText(
9884                                                        R.string.android_upgrading_complete),
9885                                                        false);
9886                                                systemReady(goingCallback);
9887                                            }
9888                                        });
9889                                    }
9890                                };
9891                            }
9892                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9893                                    + " for user " + users[j]);
9894                            broadcastIntentLocked(null, null, intent, null, finisher,
9895                                    0, null, null, null, AppOpsManager.OP_NONE,
9896                                    true, false, MY_PID, Process.SYSTEM_UID,
9897                                    users[j]);
9898                            if (finisher != null) {
9899                                mWaitingUpdate = true;
9900                            }
9901                        }
9902                    }
9903                }
9904                if (mWaitingUpdate) {
9905                    return;
9906                }
9907                mDidUpdate = true;
9908            }
9909
9910            mAppOpsService.systemReady();
9911            mUsageStatsService.systemReady();
9912            mSystemReady = true;
9913        }
9914
9915        ArrayList<ProcessRecord> procsToKill = null;
9916        synchronized(mPidsSelfLocked) {
9917            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9918                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9919                if (!isAllowedWhileBooting(proc.info)){
9920                    if (procsToKill == null) {
9921                        procsToKill = new ArrayList<ProcessRecord>();
9922                    }
9923                    procsToKill.add(proc);
9924                }
9925            }
9926        }
9927
9928        synchronized(this) {
9929            if (procsToKill != null) {
9930                for (int i=procsToKill.size()-1; i>=0; i--) {
9931                    ProcessRecord proc = procsToKill.get(i);
9932                    Slog.i(TAG, "Removing system update proc: " + proc);
9933                    removeProcessLocked(proc, true, false, "system update done");
9934                }
9935            }
9936
9937            // Now that we have cleaned up any update processes, we
9938            // are ready to start launching real processes and know that
9939            // we won't trample on them any more.
9940            mProcessesReady = true;
9941        }
9942
9943        Slog.i(TAG, "System now ready");
9944        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9945            SystemClock.uptimeMillis());
9946
9947        synchronized(this) {
9948            // Make sure we have no pre-ready processes sitting around.
9949
9950            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9951                ResolveInfo ri = mContext.getPackageManager()
9952                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9953                                STOCK_PM_FLAGS);
9954                CharSequence errorMsg = null;
9955                if (ri != null) {
9956                    ActivityInfo ai = ri.activityInfo;
9957                    ApplicationInfo app = ai.applicationInfo;
9958                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9959                        mTopAction = Intent.ACTION_FACTORY_TEST;
9960                        mTopData = null;
9961                        mTopComponent = new ComponentName(app.packageName,
9962                                ai.name);
9963                    } else {
9964                        errorMsg = mContext.getResources().getText(
9965                                com.android.internal.R.string.factorytest_not_system);
9966                    }
9967                } else {
9968                    errorMsg = mContext.getResources().getText(
9969                            com.android.internal.R.string.factorytest_no_action);
9970                }
9971                if (errorMsg != null) {
9972                    mTopAction = null;
9973                    mTopData = null;
9974                    mTopComponent = null;
9975                    Message msg = Message.obtain();
9976                    msg.what = SHOW_FACTORY_ERROR_MSG;
9977                    msg.getData().putCharSequence("msg", errorMsg);
9978                    mHandler.sendMessage(msg);
9979                }
9980            }
9981        }
9982
9983        retrieveSettings();
9984
9985        synchronized (this) {
9986            readGrantedUriPermissionsLocked();
9987        }
9988
9989        if (goingCallback != null) goingCallback.run();
9990
9991        mSystemServiceManager.startUser(mCurrentUserId);
9992
9993        synchronized (this) {
9994            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9995                try {
9996                    List apps = AppGlobals.getPackageManager().
9997                        getPersistentApplications(STOCK_PM_FLAGS);
9998                    if (apps != null) {
9999                        int N = apps.size();
10000                        int i;
10001                        for (i=0; i<N; i++) {
10002                            ApplicationInfo info
10003                                = (ApplicationInfo)apps.get(i);
10004                            if (info != null &&
10005                                    !info.packageName.equals("android")) {
10006                                addAppLocked(info, false, null /* ABI override */);
10007                            }
10008                        }
10009                    }
10010                } catch (RemoteException ex) {
10011                    // pm is in same process, this will never happen.
10012                }
10013            }
10014
10015            // Start up initial activity.
10016            mBooting = true;
10017
10018            try {
10019                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10020                    Message msg = Message.obtain();
10021                    msg.what = SHOW_UID_ERROR_MSG;
10022                    mHandler.sendMessage(msg);
10023                }
10024            } catch (RemoteException e) {
10025            }
10026
10027            long ident = Binder.clearCallingIdentity();
10028            try {
10029                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10030                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10031                        | Intent.FLAG_RECEIVER_FOREGROUND);
10032                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10033                broadcastIntentLocked(null, null, intent,
10034                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10035                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10036                intent = new Intent(Intent.ACTION_USER_STARTING);
10037                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10038                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10039                broadcastIntentLocked(null, null, intent,
10040                        null, new IIntentReceiver.Stub() {
10041                            @Override
10042                            public void performReceive(Intent intent, int resultCode, String data,
10043                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10044                                    throws RemoteException {
10045                            }
10046                        }, 0, null, null,
10047                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10048                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10049            } catch (Throwable t) {
10050                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10051            } finally {
10052                Binder.restoreCallingIdentity(ident);
10053            }
10054            mStackSupervisor.resumeTopActivitiesLocked();
10055            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10056        }
10057    }
10058
10059    private boolean makeAppCrashingLocked(ProcessRecord app,
10060            String shortMsg, String longMsg, String stackTrace) {
10061        app.crashing = true;
10062        app.crashingReport = generateProcessError(app,
10063                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10064        startAppProblemLocked(app);
10065        app.stopFreezingAllLocked();
10066        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10067    }
10068
10069    private void makeAppNotRespondingLocked(ProcessRecord app,
10070            String activity, String shortMsg, String longMsg) {
10071        app.notResponding = true;
10072        app.notRespondingReport = generateProcessError(app,
10073                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10074                activity, shortMsg, longMsg, null);
10075        startAppProblemLocked(app);
10076        app.stopFreezingAllLocked();
10077    }
10078
10079    /**
10080     * Generate a process error record, suitable for attachment to a ProcessRecord.
10081     *
10082     * @param app The ProcessRecord in which the error occurred.
10083     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10084     *                      ActivityManager.AppErrorStateInfo
10085     * @param activity The activity associated with the crash, if known.
10086     * @param shortMsg Short message describing the crash.
10087     * @param longMsg Long message describing the crash.
10088     * @param stackTrace Full crash stack trace, may be null.
10089     *
10090     * @return Returns a fully-formed AppErrorStateInfo record.
10091     */
10092    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10093            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10094        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10095
10096        report.condition = condition;
10097        report.processName = app.processName;
10098        report.pid = app.pid;
10099        report.uid = app.info.uid;
10100        report.tag = activity;
10101        report.shortMsg = shortMsg;
10102        report.longMsg = longMsg;
10103        report.stackTrace = stackTrace;
10104
10105        return report;
10106    }
10107
10108    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10109        synchronized (this) {
10110            app.crashing = false;
10111            app.crashingReport = null;
10112            app.notResponding = false;
10113            app.notRespondingReport = null;
10114            if (app.anrDialog == fromDialog) {
10115                app.anrDialog = null;
10116            }
10117            if (app.waitDialog == fromDialog) {
10118                app.waitDialog = null;
10119            }
10120            if (app.pid > 0 && app.pid != MY_PID) {
10121                handleAppCrashLocked(app, null, null, null);
10122                killUnneededProcessLocked(app, "user request after error");
10123            }
10124        }
10125    }
10126
10127    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10128            String stackTrace) {
10129        long now = SystemClock.uptimeMillis();
10130
10131        Long crashTime;
10132        if (!app.isolated) {
10133            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10134        } else {
10135            crashTime = null;
10136        }
10137        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10138            // This process loses!
10139            Slog.w(TAG, "Process " + app.info.processName
10140                    + " has crashed too many times: killing!");
10141            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10142                    app.userId, app.info.processName, app.uid);
10143            mStackSupervisor.handleAppCrashLocked(app);
10144            if (!app.persistent) {
10145                // We don't want to start this process again until the user
10146                // explicitly does so...  but for persistent process, we really
10147                // need to keep it running.  If a persistent process is actually
10148                // repeatedly crashing, then badness for everyone.
10149                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10150                        app.info.processName);
10151                if (!app.isolated) {
10152                    // XXX We don't have a way to mark isolated processes
10153                    // as bad, since they don't have a peristent identity.
10154                    mBadProcesses.put(app.info.processName, app.uid,
10155                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10156                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10157                }
10158                app.bad = true;
10159                app.removed = true;
10160                // Don't let services in this process be restarted and potentially
10161                // annoy the user repeatedly.  Unless it is persistent, since those
10162                // processes run critical code.
10163                removeProcessLocked(app, false, false, "crash");
10164                mStackSupervisor.resumeTopActivitiesLocked();
10165                return false;
10166            }
10167            mStackSupervisor.resumeTopActivitiesLocked();
10168        } else {
10169            mStackSupervisor.finishTopRunningActivityLocked(app);
10170        }
10171
10172        // Bump up the crash count of any services currently running in the proc.
10173        for (int i=app.services.size()-1; i>=0; i--) {
10174            // Any services running in the application need to be placed
10175            // back in the pending list.
10176            ServiceRecord sr = app.services.valueAt(i);
10177            sr.crashCount++;
10178        }
10179
10180        // If the crashing process is what we consider to be the "home process" and it has been
10181        // replaced by a third-party app, clear the package preferred activities from packages
10182        // with a home activity running in the process to prevent a repeatedly crashing app
10183        // from blocking the user to manually clear the list.
10184        final ArrayList<ActivityRecord> activities = app.activities;
10185        if (app == mHomeProcess && activities.size() > 0
10186                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10187            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10188                final ActivityRecord r = activities.get(activityNdx);
10189                if (r.isHomeActivity()) {
10190                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10191                    try {
10192                        ActivityThread.getPackageManager()
10193                                .clearPackagePreferredActivities(r.packageName);
10194                    } catch (RemoteException c) {
10195                        // pm is in same process, this will never happen.
10196                    }
10197                }
10198            }
10199        }
10200
10201        if (!app.isolated) {
10202            // XXX Can't keep track of crash times for isolated processes,
10203            // because they don't have a perisistent identity.
10204            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10205        }
10206
10207        return true;
10208    }
10209
10210    void startAppProblemLocked(ProcessRecord app) {
10211        if (app.userId == mCurrentUserId) {
10212            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10213                    mContext, app.info.packageName, app.info.flags);
10214        } else {
10215            // If this app is not running under the current user, then we
10216            // can't give it a report button because that would require
10217            // launching the report UI under a different user.
10218            app.errorReportReceiver = null;
10219        }
10220        skipCurrentReceiverLocked(app);
10221    }
10222
10223    void skipCurrentReceiverLocked(ProcessRecord app) {
10224        for (BroadcastQueue queue : mBroadcastQueues) {
10225            queue.skipCurrentReceiverLocked(app);
10226        }
10227    }
10228
10229    /**
10230     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10231     * The application process will exit immediately after this call returns.
10232     * @param app object of the crashing app, null for the system server
10233     * @param crashInfo describing the exception
10234     */
10235    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10236        ProcessRecord r = findAppProcess(app, "Crash");
10237        final String processName = app == null ? "system_server"
10238                : (r == null ? "unknown" : r.processName);
10239
10240        handleApplicationCrashInner("crash", r, processName, crashInfo);
10241    }
10242
10243    /* Native crash reporting uses this inner version because it needs to be somewhat
10244     * decoupled from the AM-managed cleanup lifecycle
10245     */
10246    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10247            ApplicationErrorReport.CrashInfo crashInfo) {
10248        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10249                UserHandle.getUserId(Binder.getCallingUid()), processName,
10250                r == null ? -1 : r.info.flags,
10251                crashInfo.exceptionClassName,
10252                crashInfo.exceptionMessage,
10253                crashInfo.throwFileName,
10254                crashInfo.throwLineNumber);
10255
10256        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10257
10258        crashApplication(r, crashInfo);
10259    }
10260
10261    public void handleApplicationStrictModeViolation(
10262            IBinder app,
10263            int violationMask,
10264            StrictMode.ViolationInfo info) {
10265        ProcessRecord r = findAppProcess(app, "StrictMode");
10266        if (r == null) {
10267            return;
10268        }
10269
10270        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10271            Integer stackFingerprint = info.hashCode();
10272            boolean logIt = true;
10273            synchronized (mAlreadyLoggedViolatedStacks) {
10274                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10275                    logIt = false;
10276                    // TODO: sub-sample into EventLog for these, with
10277                    // the info.durationMillis?  Then we'd get
10278                    // the relative pain numbers, without logging all
10279                    // the stack traces repeatedly.  We'd want to do
10280                    // likewise in the client code, which also does
10281                    // dup suppression, before the Binder call.
10282                } else {
10283                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10284                        mAlreadyLoggedViolatedStacks.clear();
10285                    }
10286                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10287                }
10288            }
10289            if (logIt) {
10290                logStrictModeViolationToDropBox(r, info);
10291            }
10292        }
10293
10294        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10295            AppErrorResult result = new AppErrorResult();
10296            synchronized (this) {
10297                final long origId = Binder.clearCallingIdentity();
10298
10299                Message msg = Message.obtain();
10300                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10301                HashMap<String, Object> data = new HashMap<String, Object>();
10302                data.put("result", result);
10303                data.put("app", r);
10304                data.put("violationMask", violationMask);
10305                data.put("info", info);
10306                msg.obj = data;
10307                mHandler.sendMessage(msg);
10308
10309                Binder.restoreCallingIdentity(origId);
10310            }
10311            int res = result.get();
10312            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10313        }
10314    }
10315
10316    // Depending on the policy in effect, there could be a bunch of
10317    // these in quick succession so we try to batch these together to
10318    // minimize disk writes, number of dropbox entries, and maximize
10319    // compression, by having more fewer, larger records.
10320    private void logStrictModeViolationToDropBox(
10321            ProcessRecord process,
10322            StrictMode.ViolationInfo info) {
10323        if (info == null) {
10324            return;
10325        }
10326        final boolean isSystemApp = process == null ||
10327                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10328                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10329        final String processName = process == null ? "unknown" : process.processName;
10330        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10331        final DropBoxManager dbox = (DropBoxManager)
10332                mContext.getSystemService(Context.DROPBOX_SERVICE);
10333
10334        // Exit early if the dropbox isn't configured to accept this report type.
10335        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10336
10337        boolean bufferWasEmpty;
10338        boolean needsFlush;
10339        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10340        synchronized (sb) {
10341            bufferWasEmpty = sb.length() == 0;
10342            appendDropBoxProcessHeaders(process, processName, sb);
10343            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10344            sb.append("System-App: ").append(isSystemApp).append("\n");
10345            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10346            if (info.violationNumThisLoop != 0) {
10347                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10348            }
10349            if (info.numAnimationsRunning != 0) {
10350                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10351            }
10352            if (info.broadcastIntentAction != null) {
10353                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10354            }
10355            if (info.durationMillis != -1) {
10356                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10357            }
10358            if (info.numInstances != -1) {
10359                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10360            }
10361            if (info.tags != null) {
10362                for (String tag : info.tags) {
10363                    sb.append("Span-Tag: ").append(tag).append("\n");
10364                }
10365            }
10366            sb.append("\n");
10367            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10368                sb.append(info.crashInfo.stackTrace);
10369            }
10370            sb.append("\n");
10371
10372            // Only buffer up to ~64k.  Various logging bits truncate
10373            // things at 128k.
10374            needsFlush = (sb.length() > 64 * 1024);
10375        }
10376
10377        // Flush immediately if the buffer's grown too large, or this
10378        // is a non-system app.  Non-system apps are isolated with a
10379        // different tag & policy and not batched.
10380        //
10381        // Batching is useful during internal testing with
10382        // StrictMode settings turned up high.  Without batching,
10383        // thousands of separate files could be created on boot.
10384        if (!isSystemApp || needsFlush) {
10385            new Thread("Error dump: " + dropboxTag) {
10386                @Override
10387                public void run() {
10388                    String report;
10389                    synchronized (sb) {
10390                        report = sb.toString();
10391                        sb.delete(0, sb.length());
10392                        sb.trimToSize();
10393                    }
10394                    if (report.length() != 0) {
10395                        dbox.addText(dropboxTag, report);
10396                    }
10397                }
10398            }.start();
10399            return;
10400        }
10401
10402        // System app batching:
10403        if (!bufferWasEmpty) {
10404            // An existing dropbox-writing thread is outstanding, so
10405            // we don't need to start it up.  The existing thread will
10406            // catch the buffer appends we just did.
10407            return;
10408        }
10409
10410        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10411        // (After this point, we shouldn't access AMS internal data structures.)
10412        new Thread("Error dump: " + dropboxTag) {
10413            @Override
10414            public void run() {
10415                // 5 second sleep to let stacks arrive and be batched together
10416                try {
10417                    Thread.sleep(5000);  // 5 seconds
10418                } catch (InterruptedException e) {}
10419
10420                String errorReport;
10421                synchronized (mStrictModeBuffer) {
10422                    errorReport = mStrictModeBuffer.toString();
10423                    if (errorReport.length() == 0) {
10424                        return;
10425                    }
10426                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10427                    mStrictModeBuffer.trimToSize();
10428                }
10429                dbox.addText(dropboxTag, errorReport);
10430            }
10431        }.start();
10432    }
10433
10434    /**
10435     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10436     * @param app object of the crashing app, null for the system server
10437     * @param tag reported by the caller
10438     * @param crashInfo describing the context of the error
10439     * @return true if the process should exit immediately (WTF is fatal)
10440     */
10441    public boolean handleApplicationWtf(IBinder app, String tag,
10442            ApplicationErrorReport.CrashInfo crashInfo) {
10443        ProcessRecord r = findAppProcess(app, "WTF");
10444        final String processName = app == null ? "system_server"
10445                : (r == null ? "unknown" : r.processName);
10446
10447        EventLog.writeEvent(EventLogTags.AM_WTF,
10448                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10449                processName,
10450                r == null ? -1 : r.info.flags,
10451                tag, crashInfo.exceptionMessage);
10452
10453        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10454
10455        if (r != null && r.pid != Process.myPid() &&
10456                Settings.Global.getInt(mContext.getContentResolver(),
10457                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10458            crashApplication(r, crashInfo);
10459            return true;
10460        } else {
10461            return false;
10462        }
10463    }
10464
10465    /**
10466     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10467     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10468     */
10469    private ProcessRecord findAppProcess(IBinder app, String reason) {
10470        if (app == null) {
10471            return null;
10472        }
10473
10474        synchronized (this) {
10475            final int NP = mProcessNames.getMap().size();
10476            for (int ip=0; ip<NP; ip++) {
10477                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10478                final int NA = apps.size();
10479                for (int ia=0; ia<NA; ia++) {
10480                    ProcessRecord p = apps.valueAt(ia);
10481                    if (p.thread != null && p.thread.asBinder() == app) {
10482                        return p;
10483                    }
10484                }
10485            }
10486
10487            Slog.w(TAG, "Can't find mystery application for " + reason
10488                    + " from pid=" + Binder.getCallingPid()
10489                    + " uid=" + Binder.getCallingUid() + ": " + app);
10490            return null;
10491        }
10492    }
10493
10494    /**
10495     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10496     * to append various headers to the dropbox log text.
10497     */
10498    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10499            StringBuilder sb) {
10500        // Watchdog thread ends up invoking this function (with
10501        // a null ProcessRecord) to add the stack file to dropbox.
10502        // Do not acquire a lock on this (am) in such cases, as it
10503        // could cause a potential deadlock, if and when watchdog
10504        // is invoked due to unavailability of lock on am and it
10505        // would prevent watchdog from killing system_server.
10506        if (process == null) {
10507            sb.append("Process: ").append(processName).append("\n");
10508            return;
10509        }
10510        // Note: ProcessRecord 'process' is guarded by the service
10511        // instance.  (notably process.pkgList, which could otherwise change
10512        // concurrently during execution of this method)
10513        synchronized (this) {
10514            sb.append("Process: ").append(processName).append("\n");
10515            int flags = process.info.flags;
10516            IPackageManager pm = AppGlobals.getPackageManager();
10517            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10518            for (int ip=0; ip<process.pkgList.size(); ip++) {
10519                String pkg = process.pkgList.keyAt(ip);
10520                sb.append("Package: ").append(pkg);
10521                try {
10522                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10523                    if (pi != null) {
10524                        sb.append(" v").append(pi.versionCode);
10525                        if (pi.versionName != null) {
10526                            sb.append(" (").append(pi.versionName).append(")");
10527                        }
10528                    }
10529                } catch (RemoteException e) {
10530                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10531                }
10532                sb.append("\n");
10533            }
10534        }
10535    }
10536
10537    private static String processClass(ProcessRecord process) {
10538        if (process == null || process.pid == MY_PID) {
10539            return "system_server";
10540        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10541            return "system_app";
10542        } else {
10543            return "data_app";
10544        }
10545    }
10546
10547    /**
10548     * Write a description of an error (crash, WTF, ANR) to the drop box.
10549     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10550     * @param process which caused the error, null means the system server
10551     * @param activity which triggered the error, null if unknown
10552     * @param parent activity related to the error, null if unknown
10553     * @param subject line related to the error, null if absent
10554     * @param report in long form describing the error, null if absent
10555     * @param logFile to include in the report, null if none
10556     * @param crashInfo giving an application stack trace, null if absent
10557     */
10558    public void addErrorToDropBox(String eventType,
10559            ProcessRecord process, String processName, ActivityRecord activity,
10560            ActivityRecord parent, String subject,
10561            final String report, final File logFile,
10562            final ApplicationErrorReport.CrashInfo crashInfo) {
10563        // NOTE -- this must never acquire the ActivityManagerService lock,
10564        // otherwise the watchdog may be prevented from resetting the system.
10565
10566        final String dropboxTag = processClass(process) + "_" + eventType;
10567        final DropBoxManager dbox = (DropBoxManager)
10568                mContext.getSystemService(Context.DROPBOX_SERVICE);
10569
10570        // Exit early if the dropbox isn't configured to accept this report type.
10571        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10572
10573        final StringBuilder sb = new StringBuilder(1024);
10574        appendDropBoxProcessHeaders(process, processName, sb);
10575        if (activity != null) {
10576            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10577        }
10578        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10579            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10580        }
10581        if (parent != null && parent != activity) {
10582            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10583        }
10584        if (subject != null) {
10585            sb.append("Subject: ").append(subject).append("\n");
10586        }
10587        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10588        if (Debug.isDebuggerConnected()) {
10589            sb.append("Debugger: Connected\n");
10590        }
10591        sb.append("\n");
10592
10593        // Do the rest in a worker thread to avoid blocking the caller on I/O
10594        // (After this point, we shouldn't access AMS internal data structures.)
10595        Thread worker = new Thread("Error dump: " + dropboxTag) {
10596            @Override
10597            public void run() {
10598                if (report != null) {
10599                    sb.append(report);
10600                }
10601                if (logFile != null) {
10602                    try {
10603                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10604                                    "\n\n[[TRUNCATED]]"));
10605                    } catch (IOException e) {
10606                        Slog.e(TAG, "Error reading " + logFile, e);
10607                    }
10608                }
10609                if (crashInfo != null && crashInfo.stackTrace != null) {
10610                    sb.append(crashInfo.stackTrace);
10611                }
10612
10613                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10614                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10615                if (lines > 0) {
10616                    sb.append("\n");
10617
10618                    // Merge several logcat streams, and take the last N lines
10619                    InputStreamReader input = null;
10620                    try {
10621                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10622                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10623                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10624
10625                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10626                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10627                        input = new InputStreamReader(logcat.getInputStream());
10628
10629                        int num;
10630                        char[] buf = new char[8192];
10631                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10632                    } catch (IOException e) {
10633                        Slog.e(TAG, "Error running logcat", e);
10634                    } finally {
10635                        if (input != null) try { input.close(); } catch (IOException e) {}
10636                    }
10637                }
10638
10639                dbox.addText(dropboxTag, sb.toString());
10640            }
10641        };
10642
10643        if (process == null) {
10644            // If process is null, we are being called from some internal code
10645            // and may be about to die -- run this synchronously.
10646            worker.run();
10647        } else {
10648            worker.start();
10649        }
10650    }
10651
10652    /**
10653     * Bring up the "unexpected error" dialog box for a crashing app.
10654     * Deal with edge cases (intercepts from instrumented applications,
10655     * ActivityController, error intent receivers, that sort of thing).
10656     * @param r the application crashing
10657     * @param crashInfo describing the failure
10658     */
10659    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10660        long timeMillis = System.currentTimeMillis();
10661        String shortMsg = crashInfo.exceptionClassName;
10662        String longMsg = crashInfo.exceptionMessage;
10663        String stackTrace = crashInfo.stackTrace;
10664        if (shortMsg != null && longMsg != null) {
10665            longMsg = shortMsg + ": " + longMsg;
10666        } else if (shortMsg != null) {
10667            longMsg = shortMsg;
10668        }
10669
10670        AppErrorResult result = new AppErrorResult();
10671        synchronized (this) {
10672            if (mController != null) {
10673                try {
10674                    String name = r != null ? r.processName : null;
10675                    int pid = r != null ? r.pid : Binder.getCallingPid();
10676                    if (!mController.appCrashed(name, pid,
10677                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10678                        Slog.w(TAG, "Force-killing crashed app " + name
10679                                + " at watcher's request");
10680                        Process.killProcess(pid);
10681                        return;
10682                    }
10683                } catch (RemoteException e) {
10684                    mController = null;
10685                    Watchdog.getInstance().setActivityController(null);
10686                }
10687            }
10688
10689            final long origId = Binder.clearCallingIdentity();
10690
10691            // If this process is running instrumentation, finish it.
10692            if (r != null && r.instrumentationClass != null) {
10693                Slog.w(TAG, "Error in app " + r.processName
10694                      + " running instrumentation " + r.instrumentationClass + ":");
10695                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10696                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10697                Bundle info = new Bundle();
10698                info.putString("shortMsg", shortMsg);
10699                info.putString("longMsg", longMsg);
10700                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10701                Binder.restoreCallingIdentity(origId);
10702                return;
10703            }
10704
10705            // If we can't identify the process or it's already exceeded its crash quota,
10706            // quit right away without showing a crash dialog.
10707            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10708                Binder.restoreCallingIdentity(origId);
10709                return;
10710            }
10711
10712            Message msg = Message.obtain();
10713            msg.what = SHOW_ERROR_MSG;
10714            HashMap data = new HashMap();
10715            data.put("result", result);
10716            data.put("app", r);
10717            msg.obj = data;
10718            mHandler.sendMessage(msg);
10719
10720            Binder.restoreCallingIdentity(origId);
10721        }
10722
10723        int res = result.get();
10724
10725        Intent appErrorIntent = null;
10726        synchronized (this) {
10727            if (r != null && !r.isolated) {
10728                // XXX Can't keep track of crash time for isolated processes,
10729                // since they don't have a persistent identity.
10730                mProcessCrashTimes.put(r.info.processName, r.uid,
10731                        SystemClock.uptimeMillis());
10732            }
10733            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10734                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10735            }
10736        }
10737
10738        if (appErrorIntent != null) {
10739            try {
10740                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10741            } catch (ActivityNotFoundException e) {
10742                Slog.w(TAG, "bug report receiver dissappeared", e);
10743            }
10744        }
10745    }
10746
10747    Intent createAppErrorIntentLocked(ProcessRecord r,
10748            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10749        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10750        if (report == null) {
10751            return null;
10752        }
10753        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10754        result.setComponent(r.errorReportReceiver);
10755        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10756        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10757        return result;
10758    }
10759
10760    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10761            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10762        if (r.errorReportReceiver == null) {
10763            return null;
10764        }
10765
10766        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10767            return null;
10768        }
10769
10770        ApplicationErrorReport report = new ApplicationErrorReport();
10771        report.packageName = r.info.packageName;
10772        report.installerPackageName = r.errorReportReceiver.getPackageName();
10773        report.processName = r.processName;
10774        report.time = timeMillis;
10775        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10776
10777        if (r.crashing || r.forceCrashReport) {
10778            report.type = ApplicationErrorReport.TYPE_CRASH;
10779            report.crashInfo = crashInfo;
10780        } else if (r.notResponding) {
10781            report.type = ApplicationErrorReport.TYPE_ANR;
10782            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10783
10784            report.anrInfo.activity = r.notRespondingReport.tag;
10785            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10786            report.anrInfo.info = r.notRespondingReport.longMsg;
10787        }
10788
10789        return report;
10790    }
10791
10792    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10793        enforceNotIsolatedCaller("getProcessesInErrorState");
10794        // assume our apps are happy - lazy create the list
10795        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10796
10797        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10798                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10799        int userId = UserHandle.getUserId(Binder.getCallingUid());
10800
10801        synchronized (this) {
10802
10803            // iterate across all processes
10804            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10805                ProcessRecord app = mLruProcesses.get(i);
10806                if (!allUsers && app.userId != userId) {
10807                    continue;
10808                }
10809                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10810                    // This one's in trouble, so we'll generate a report for it
10811                    // crashes are higher priority (in case there's a crash *and* an anr)
10812                    ActivityManager.ProcessErrorStateInfo report = null;
10813                    if (app.crashing) {
10814                        report = app.crashingReport;
10815                    } else if (app.notResponding) {
10816                        report = app.notRespondingReport;
10817                    }
10818
10819                    if (report != null) {
10820                        if (errList == null) {
10821                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10822                        }
10823                        errList.add(report);
10824                    } else {
10825                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10826                                " crashing = " + app.crashing +
10827                                " notResponding = " + app.notResponding);
10828                    }
10829                }
10830            }
10831        }
10832
10833        return errList;
10834    }
10835
10836    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10837        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10838            if (currApp != null) {
10839                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10840            }
10841            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10842        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10843            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10844        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10845            if (currApp != null) {
10846                currApp.lru = 0;
10847            }
10848            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10849        } else if (adj >= ProcessList.SERVICE_ADJ) {
10850            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10851        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10852            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10853        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10854            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10855        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10856            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10857        } else {
10858            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10859        }
10860    }
10861
10862    private void fillInProcMemInfo(ProcessRecord app,
10863            ActivityManager.RunningAppProcessInfo outInfo) {
10864        outInfo.pid = app.pid;
10865        outInfo.uid = app.info.uid;
10866        if (mHeavyWeightProcess == app) {
10867            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10868        }
10869        if (app.persistent) {
10870            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10871        }
10872        if (app.activities.size() > 0) {
10873            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10874        }
10875        outInfo.lastTrimLevel = app.trimMemoryLevel;
10876        int adj = app.curAdj;
10877        outInfo.importance = oomAdjToImportance(adj, outInfo);
10878        outInfo.importanceReasonCode = app.adjTypeCode;
10879        outInfo.processState = app.curProcState;
10880    }
10881
10882    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10883        enforceNotIsolatedCaller("getRunningAppProcesses");
10884        // Lazy instantiation of list
10885        List<ActivityManager.RunningAppProcessInfo> runList = null;
10886        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10887                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10888        int userId = UserHandle.getUserId(Binder.getCallingUid());
10889        synchronized (this) {
10890            // Iterate across all processes
10891            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10892                ProcessRecord app = mLruProcesses.get(i);
10893                if (!allUsers && app.userId != userId) {
10894                    continue;
10895                }
10896                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10897                    // Generate process state info for running application
10898                    ActivityManager.RunningAppProcessInfo currApp =
10899                        new ActivityManager.RunningAppProcessInfo(app.processName,
10900                                app.pid, app.getPackageList());
10901                    fillInProcMemInfo(app, currApp);
10902                    if (app.adjSource instanceof ProcessRecord) {
10903                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10904                        currApp.importanceReasonImportance = oomAdjToImportance(
10905                                app.adjSourceOom, null);
10906                    } else if (app.adjSource instanceof ActivityRecord) {
10907                        ActivityRecord r = (ActivityRecord)app.adjSource;
10908                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10909                    }
10910                    if (app.adjTarget instanceof ComponentName) {
10911                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10912                    }
10913                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10914                    //        + " lru=" + currApp.lru);
10915                    if (runList == null) {
10916                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10917                    }
10918                    runList.add(currApp);
10919                }
10920            }
10921        }
10922        return runList;
10923    }
10924
10925    public List<ApplicationInfo> getRunningExternalApplications() {
10926        enforceNotIsolatedCaller("getRunningExternalApplications");
10927        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10928        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10929        if (runningApps != null && runningApps.size() > 0) {
10930            Set<String> extList = new HashSet<String>();
10931            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10932                if (app.pkgList != null) {
10933                    for (String pkg : app.pkgList) {
10934                        extList.add(pkg);
10935                    }
10936                }
10937            }
10938            IPackageManager pm = AppGlobals.getPackageManager();
10939            for (String pkg : extList) {
10940                try {
10941                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10942                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10943                        retList.add(info);
10944                    }
10945                } catch (RemoteException e) {
10946                }
10947            }
10948        }
10949        return retList;
10950    }
10951
10952    @Override
10953    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10954        enforceNotIsolatedCaller("getMyMemoryState");
10955        synchronized (this) {
10956            ProcessRecord proc;
10957            synchronized (mPidsSelfLocked) {
10958                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10959            }
10960            fillInProcMemInfo(proc, outInfo);
10961        }
10962    }
10963
10964    @Override
10965    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10966        if (checkCallingPermission(android.Manifest.permission.DUMP)
10967                != PackageManager.PERMISSION_GRANTED) {
10968            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10969                    + Binder.getCallingPid()
10970                    + ", uid=" + Binder.getCallingUid()
10971                    + " without permission "
10972                    + android.Manifest.permission.DUMP);
10973            return;
10974        }
10975
10976        boolean dumpAll = false;
10977        boolean dumpClient = false;
10978        String dumpPackage = null;
10979
10980        int opti = 0;
10981        while (opti < args.length) {
10982            String opt = args[opti];
10983            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10984                break;
10985            }
10986            opti++;
10987            if ("-a".equals(opt)) {
10988                dumpAll = true;
10989            } else if ("-c".equals(opt)) {
10990                dumpClient = true;
10991            } else if ("-h".equals(opt)) {
10992                pw.println("Activity manager dump options:");
10993                pw.println("  [-a] [-c] [-h] [cmd] ...");
10994                pw.println("  cmd may be one of:");
10995                pw.println("    a[ctivities]: activity stack state");
10996                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10997                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10998                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10999                pw.println("    o[om]: out of memory management");
11000                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11001                pw.println("    provider [COMP_SPEC]: provider client-side state");
11002                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11003                pw.println("    service [COMP_SPEC]: service client-side state");
11004                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11005                pw.println("    all: dump all activities");
11006                pw.println("    top: dump the top activity");
11007                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11008                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11009                pw.println("    a partial substring in a component name, a");
11010                pw.println("    hex object identifier.");
11011                pw.println("  -a: include all available server state.");
11012                pw.println("  -c: include client state.");
11013                return;
11014            } else {
11015                pw.println("Unknown argument: " + opt + "; use -h for help");
11016            }
11017        }
11018
11019        long origId = Binder.clearCallingIdentity();
11020        boolean more = false;
11021        // Is the caller requesting to dump a particular piece of data?
11022        if (opti < args.length) {
11023            String cmd = args[opti];
11024            opti++;
11025            if ("activities".equals(cmd) || "a".equals(cmd)) {
11026                synchronized (this) {
11027                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11028                }
11029            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11030                String[] newArgs;
11031                String name;
11032                if (opti >= args.length) {
11033                    name = null;
11034                    newArgs = EMPTY_STRING_ARRAY;
11035                } else {
11036                    name = args[opti];
11037                    opti++;
11038                    newArgs = new String[args.length - opti];
11039                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11040                            args.length - opti);
11041                }
11042                synchronized (this) {
11043                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11044                }
11045            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11046                String[] newArgs;
11047                String name;
11048                if (opti >= args.length) {
11049                    name = null;
11050                    newArgs = EMPTY_STRING_ARRAY;
11051                } else {
11052                    name = args[opti];
11053                    opti++;
11054                    newArgs = new String[args.length - opti];
11055                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11056                            args.length - opti);
11057                }
11058                synchronized (this) {
11059                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11060                }
11061            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11062                String[] newArgs;
11063                String name;
11064                if (opti >= args.length) {
11065                    name = null;
11066                    newArgs = EMPTY_STRING_ARRAY;
11067                } else {
11068                    name = args[opti];
11069                    opti++;
11070                    newArgs = new String[args.length - opti];
11071                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11072                            args.length - opti);
11073                }
11074                synchronized (this) {
11075                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11076                }
11077            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11078                synchronized (this) {
11079                    dumpOomLocked(fd, pw, args, opti, true);
11080                }
11081            } else if ("provider".equals(cmd)) {
11082                String[] newArgs;
11083                String name;
11084                if (opti >= args.length) {
11085                    name = null;
11086                    newArgs = EMPTY_STRING_ARRAY;
11087                } else {
11088                    name = args[opti];
11089                    opti++;
11090                    newArgs = new String[args.length - opti];
11091                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11092                }
11093                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11094                    pw.println("No providers match: " + name);
11095                    pw.println("Use -h for help.");
11096                }
11097            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11098                synchronized (this) {
11099                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11100                }
11101            } else if ("service".equals(cmd)) {
11102                String[] newArgs;
11103                String name;
11104                if (opti >= args.length) {
11105                    name = null;
11106                    newArgs = EMPTY_STRING_ARRAY;
11107                } else {
11108                    name = args[opti];
11109                    opti++;
11110                    newArgs = new String[args.length - opti];
11111                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11112                            args.length - opti);
11113                }
11114                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11115                    pw.println("No services match: " + name);
11116                    pw.println("Use -h for help.");
11117                }
11118            } else if ("package".equals(cmd)) {
11119                String[] newArgs;
11120                if (opti >= args.length) {
11121                    pw.println("package: no package name specified");
11122                    pw.println("Use -h for help.");
11123                } else {
11124                    dumpPackage = args[opti];
11125                    opti++;
11126                    newArgs = new String[args.length - opti];
11127                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11128                            args.length - opti);
11129                    args = newArgs;
11130                    opti = 0;
11131                    more = true;
11132                }
11133            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11134                synchronized (this) {
11135                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11136                }
11137            } else {
11138                // Dumping a single activity?
11139                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11140                    pw.println("Bad activity command, or no activities match: " + cmd);
11141                    pw.println("Use -h for help.");
11142                }
11143            }
11144            if (!more) {
11145                Binder.restoreCallingIdentity(origId);
11146                return;
11147            }
11148        }
11149
11150        // No piece of data specified, dump everything.
11151        synchronized (this) {
11152            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11153            pw.println();
11154            if (dumpAll) {
11155                pw.println("-------------------------------------------------------------------------------");
11156            }
11157            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11158            pw.println();
11159            if (dumpAll) {
11160                pw.println("-------------------------------------------------------------------------------");
11161            }
11162            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11163            pw.println();
11164            if (dumpAll) {
11165                pw.println("-------------------------------------------------------------------------------");
11166            }
11167            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11168            pw.println();
11169            if (dumpAll) {
11170                pw.println("-------------------------------------------------------------------------------");
11171            }
11172            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11173            pw.println();
11174            if (dumpAll) {
11175                pw.println("-------------------------------------------------------------------------------");
11176            }
11177            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11178        }
11179        Binder.restoreCallingIdentity(origId);
11180    }
11181
11182    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11183            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11184        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11185
11186        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11187                dumpPackage);
11188        boolean needSep = printedAnything;
11189
11190        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11191                dumpPackage, needSep, "  mFocusedActivity: ");
11192        if (printed) {
11193            printedAnything = true;
11194            needSep = false;
11195        }
11196
11197        if (dumpPackage == null) {
11198            if (needSep) {
11199                pw.println();
11200            }
11201            needSep = true;
11202            printedAnything = true;
11203            mStackSupervisor.dump(pw, "  ");
11204        }
11205
11206        if (mRecentTasks.size() > 0) {
11207            boolean printedHeader = false;
11208
11209            final int N = mRecentTasks.size();
11210            for (int i=0; i<N; i++) {
11211                TaskRecord tr = mRecentTasks.get(i);
11212                if (dumpPackage != null) {
11213                    if (tr.realActivity == null ||
11214                            !dumpPackage.equals(tr.realActivity)) {
11215                        continue;
11216                    }
11217                }
11218                if (!printedHeader) {
11219                    if (needSep) {
11220                        pw.println();
11221                    }
11222                    pw.println("  Recent tasks:");
11223                    printedHeader = true;
11224                    printedAnything = true;
11225                }
11226                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11227                        pw.println(tr);
11228                if (dumpAll) {
11229                    mRecentTasks.get(i).dump(pw, "    ");
11230                }
11231            }
11232        }
11233
11234        if (!printedAnything) {
11235            pw.println("  (nothing)");
11236        }
11237    }
11238
11239    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11240            int opti, boolean dumpAll, String dumpPackage) {
11241        boolean needSep = false;
11242        boolean printedAnything = false;
11243        int numPers = 0;
11244
11245        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11246
11247        if (dumpAll) {
11248            final int NP = mProcessNames.getMap().size();
11249            for (int ip=0; ip<NP; ip++) {
11250                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11251                final int NA = procs.size();
11252                for (int ia=0; ia<NA; ia++) {
11253                    ProcessRecord r = procs.valueAt(ia);
11254                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11255                        continue;
11256                    }
11257                    if (!needSep) {
11258                        pw.println("  All known processes:");
11259                        needSep = true;
11260                        printedAnything = true;
11261                    }
11262                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11263                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11264                        pw.print(" "); pw.println(r);
11265                    r.dump(pw, "    ");
11266                    if (r.persistent) {
11267                        numPers++;
11268                    }
11269                }
11270            }
11271        }
11272
11273        if (mIsolatedProcesses.size() > 0) {
11274            boolean printed = false;
11275            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11276                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11277                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11278                    continue;
11279                }
11280                if (!printed) {
11281                    if (needSep) {
11282                        pw.println();
11283                    }
11284                    pw.println("  Isolated process list (sorted by uid):");
11285                    printedAnything = true;
11286                    printed = true;
11287                    needSep = true;
11288                }
11289                pw.println(String.format("%sIsolated #%2d: %s",
11290                        "    ", i, r.toString()));
11291            }
11292        }
11293
11294        if (mLruProcesses.size() > 0) {
11295            if (needSep) {
11296                pw.println();
11297            }
11298            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11299                    pw.print(" total, non-act at ");
11300                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11301                    pw.print(", non-svc at ");
11302                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11303                    pw.println("):");
11304            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11305            needSep = true;
11306            printedAnything = true;
11307        }
11308
11309        if (dumpAll || dumpPackage != null) {
11310            synchronized (mPidsSelfLocked) {
11311                boolean printed = false;
11312                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11313                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11314                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11315                        continue;
11316                    }
11317                    if (!printed) {
11318                        if (needSep) pw.println();
11319                        needSep = true;
11320                        pw.println("  PID mappings:");
11321                        printed = true;
11322                        printedAnything = true;
11323                    }
11324                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11325                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11326                }
11327            }
11328        }
11329
11330        if (mForegroundProcesses.size() > 0) {
11331            synchronized (mPidsSelfLocked) {
11332                boolean printed = false;
11333                for (int i=0; i<mForegroundProcesses.size(); i++) {
11334                    ProcessRecord r = mPidsSelfLocked.get(
11335                            mForegroundProcesses.valueAt(i).pid);
11336                    if (dumpPackage != null && (r == null
11337                            || !r.pkgList.containsKey(dumpPackage))) {
11338                        continue;
11339                    }
11340                    if (!printed) {
11341                        if (needSep) pw.println();
11342                        needSep = true;
11343                        pw.println("  Foreground Processes:");
11344                        printed = true;
11345                        printedAnything = true;
11346                    }
11347                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11348                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11349                }
11350            }
11351        }
11352
11353        if (mPersistentStartingProcesses.size() > 0) {
11354            if (needSep) pw.println();
11355            needSep = true;
11356            printedAnything = true;
11357            pw.println("  Persisent processes that are starting:");
11358            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11359                    "Starting Norm", "Restarting PERS", dumpPackage);
11360        }
11361
11362        if (mRemovedProcesses.size() > 0) {
11363            if (needSep) pw.println();
11364            needSep = true;
11365            printedAnything = true;
11366            pw.println("  Processes that are being removed:");
11367            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11368                    "Removed Norm", "Removed PERS", dumpPackage);
11369        }
11370
11371        if (mProcessesOnHold.size() > 0) {
11372            if (needSep) pw.println();
11373            needSep = true;
11374            printedAnything = true;
11375            pw.println("  Processes that are on old until the system is ready:");
11376            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11377                    "OnHold Norm", "OnHold PERS", dumpPackage);
11378        }
11379
11380        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11381
11382        if (mProcessCrashTimes.getMap().size() > 0) {
11383            boolean printed = false;
11384            long now = SystemClock.uptimeMillis();
11385            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11386            final int NP = pmap.size();
11387            for (int ip=0; ip<NP; ip++) {
11388                String pname = pmap.keyAt(ip);
11389                SparseArray<Long> uids = pmap.valueAt(ip);
11390                final int N = uids.size();
11391                for (int i=0; i<N; i++) {
11392                    int puid = uids.keyAt(i);
11393                    ProcessRecord r = mProcessNames.get(pname, puid);
11394                    if (dumpPackage != null && (r == null
11395                            || !r.pkgList.containsKey(dumpPackage))) {
11396                        continue;
11397                    }
11398                    if (!printed) {
11399                        if (needSep) pw.println();
11400                        needSep = true;
11401                        pw.println("  Time since processes crashed:");
11402                        printed = true;
11403                        printedAnything = true;
11404                    }
11405                    pw.print("    Process "); pw.print(pname);
11406                            pw.print(" uid "); pw.print(puid);
11407                            pw.print(": last crashed ");
11408                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11409                            pw.println(" ago");
11410                }
11411            }
11412        }
11413
11414        if (mBadProcesses.getMap().size() > 0) {
11415            boolean printed = false;
11416            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11417            final int NP = pmap.size();
11418            for (int ip=0; ip<NP; ip++) {
11419                String pname = pmap.keyAt(ip);
11420                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11421                final int N = uids.size();
11422                for (int i=0; i<N; i++) {
11423                    int puid = uids.keyAt(i);
11424                    ProcessRecord r = mProcessNames.get(pname, puid);
11425                    if (dumpPackage != null && (r == null
11426                            || !r.pkgList.containsKey(dumpPackage))) {
11427                        continue;
11428                    }
11429                    if (!printed) {
11430                        if (needSep) pw.println();
11431                        needSep = true;
11432                        pw.println("  Bad processes:");
11433                        printedAnything = true;
11434                    }
11435                    BadProcessInfo info = uids.valueAt(i);
11436                    pw.print("    Bad process "); pw.print(pname);
11437                            pw.print(" uid "); pw.print(puid);
11438                            pw.print(": crashed at time "); pw.println(info.time);
11439                    if (info.shortMsg != null) {
11440                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11441                    }
11442                    if (info.longMsg != null) {
11443                        pw.print("      Long msg: "); pw.println(info.longMsg);
11444                    }
11445                    if (info.stack != null) {
11446                        pw.println("      Stack:");
11447                        int lastPos = 0;
11448                        for (int pos=0; pos<info.stack.length(); pos++) {
11449                            if (info.stack.charAt(pos) == '\n') {
11450                                pw.print("        ");
11451                                pw.write(info.stack, lastPos, pos-lastPos);
11452                                pw.println();
11453                                lastPos = pos+1;
11454                            }
11455                        }
11456                        if (lastPos < info.stack.length()) {
11457                            pw.print("        ");
11458                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11459                            pw.println();
11460                        }
11461                    }
11462                }
11463            }
11464        }
11465
11466        if (dumpPackage == null) {
11467            pw.println();
11468            needSep = false;
11469            pw.println("  mStartedUsers:");
11470            for (int i=0; i<mStartedUsers.size(); i++) {
11471                UserStartedState uss = mStartedUsers.valueAt(i);
11472                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11473                        pw.print(": "); uss.dump("", pw);
11474            }
11475            pw.print("  mStartedUserArray: [");
11476            for (int i=0; i<mStartedUserArray.length; i++) {
11477                if (i > 0) pw.print(", ");
11478                pw.print(mStartedUserArray[i]);
11479            }
11480            pw.println("]");
11481            pw.print("  mUserLru: [");
11482            for (int i=0; i<mUserLru.size(); i++) {
11483                if (i > 0) pw.print(", ");
11484                pw.print(mUserLru.get(i));
11485            }
11486            pw.println("]");
11487            if (dumpAll) {
11488                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11489            }
11490        }
11491        if (mHomeProcess != null && (dumpPackage == null
11492                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11493            if (needSep) {
11494                pw.println();
11495                needSep = false;
11496            }
11497            pw.println("  mHomeProcess: " + mHomeProcess);
11498        }
11499        if (mPreviousProcess != null && (dumpPackage == null
11500                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11501            if (needSep) {
11502                pw.println();
11503                needSep = false;
11504            }
11505            pw.println("  mPreviousProcess: " + mPreviousProcess);
11506        }
11507        if (dumpAll) {
11508            StringBuilder sb = new StringBuilder(128);
11509            sb.append("  mPreviousProcessVisibleTime: ");
11510            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11511            pw.println(sb);
11512        }
11513        if (mHeavyWeightProcess != null && (dumpPackage == null
11514                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11515            if (needSep) {
11516                pw.println();
11517                needSep = false;
11518            }
11519            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11520        }
11521        if (dumpPackage == null) {
11522            pw.println("  mConfiguration: " + mConfiguration);
11523        }
11524        if (dumpAll) {
11525            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11526            if (mCompatModePackages.getPackages().size() > 0) {
11527                boolean printed = false;
11528                for (Map.Entry<String, Integer> entry
11529                        : mCompatModePackages.getPackages().entrySet()) {
11530                    String pkg = entry.getKey();
11531                    int mode = entry.getValue();
11532                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11533                        continue;
11534                    }
11535                    if (!printed) {
11536                        pw.println("  mScreenCompatPackages:");
11537                        printed = true;
11538                    }
11539                    pw.print("    "); pw.print(pkg); pw.print(": ");
11540                            pw.print(mode); pw.println();
11541                }
11542            }
11543        }
11544        if (dumpPackage == null) {
11545            if (mSleeping || mWentToSleep || mLockScreenShown) {
11546                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11547                        + " mLockScreenShown " + mLockScreenShown);
11548            }
11549            if (mShuttingDown || mRunningVoice) {
11550                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11551            }
11552        }
11553        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11554                || mOrigWaitForDebugger) {
11555            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11556                    || dumpPackage.equals(mOrigDebugApp)) {
11557                if (needSep) {
11558                    pw.println();
11559                    needSep = false;
11560                }
11561                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11562                        + " mDebugTransient=" + mDebugTransient
11563                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11564            }
11565        }
11566        if (mOpenGlTraceApp != null) {
11567            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11568                if (needSep) {
11569                    pw.println();
11570                    needSep = false;
11571                }
11572                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11573            }
11574        }
11575        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11576                || mProfileFd != null) {
11577            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11578                if (needSep) {
11579                    pw.println();
11580                    needSep = false;
11581                }
11582                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11583                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11584                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11585                        + mAutoStopProfiler);
11586            }
11587        }
11588        if (dumpPackage == null) {
11589            if (mAlwaysFinishActivities || mController != null) {
11590                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11591                        + " mController=" + mController);
11592            }
11593            if (dumpAll) {
11594                pw.println("  Total persistent processes: " + numPers);
11595                pw.println("  mProcessesReady=" + mProcessesReady
11596                        + " mSystemReady=" + mSystemReady);
11597                pw.println("  mBooting=" + mBooting
11598                        + " mBooted=" + mBooted
11599                        + " mFactoryTest=" + mFactoryTest);
11600                pw.print("  mLastPowerCheckRealtime=");
11601                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11602                        pw.println("");
11603                pw.print("  mLastPowerCheckUptime=");
11604                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11605                        pw.println("");
11606                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11607                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11608                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11609                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11610                        + " (" + mLruProcesses.size() + " total)"
11611                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11612                        + " mNumServiceProcs=" + mNumServiceProcs
11613                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11614                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11615                        + " mLastMemoryLevel" + mLastMemoryLevel
11616                        + " mLastNumProcesses" + mLastNumProcesses);
11617                long now = SystemClock.uptimeMillis();
11618                pw.print("  mLastIdleTime=");
11619                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11620                        pw.print(" mLowRamSinceLastIdle=");
11621                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11622                        pw.println();
11623            }
11624        }
11625
11626        if (!printedAnything) {
11627            pw.println("  (nothing)");
11628        }
11629    }
11630
11631    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11632            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11633        if (mProcessesToGc.size() > 0) {
11634            boolean printed = false;
11635            long now = SystemClock.uptimeMillis();
11636            for (int i=0; i<mProcessesToGc.size(); i++) {
11637                ProcessRecord proc = mProcessesToGc.get(i);
11638                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11639                    continue;
11640                }
11641                if (!printed) {
11642                    if (needSep) pw.println();
11643                    needSep = true;
11644                    pw.println("  Processes that are waiting to GC:");
11645                    printed = true;
11646                }
11647                pw.print("    Process "); pw.println(proc);
11648                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11649                        pw.print(", last gced=");
11650                        pw.print(now-proc.lastRequestedGc);
11651                        pw.print(" ms ago, last lowMem=");
11652                        pw.print(now-proc.lastLowMemory);
11653                        pw.println(" ms ago");
11654
11655            }
11656        }
11657        return needSep;
11658    }
11659
11660    void printOomLevel(PrintWriter pw, String name, int adj) {
11661        pw.print("    ");
11662        if (adj >= 0) {
11663            pw.print(' ');
11664            if (adj < 10) pw.print(' ');
11665        } else {
11666            if (adj > -10) pw.print(' ');
11667        }
11668        pw.print(adj);
11669        pw.print(": ");
11670        pw.print(name);
11671        pw.print(" (");
11672        pw.print(mProcessList.getMemLevel(adj)/1024);
11673        pw.println(" kB)");
11674    }
11675
11676    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11677            int opti, boolean dumpAll) {
11678        boolean needSep = false;
11679
11680        if (mLruProcesses.size() > 0) {
11681            if (needSep) pw.println();
11682            needSep = true;
11683            pw.println("  OOM levels:");
11684            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11685            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11686            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11687            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11688            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11689            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11690            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11691            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11692            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11693            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11694            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11695            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11696            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11697
11698            if (needSep) pw.println();
11699            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11700                    pw.print(" total, non-act at ");
11701                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11702                    pw.print(", non-svc at ");
11703                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11704                    pw.println("):");
11705            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11706            needSep = true;
11707        }
11708
11709        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11710
11711        pw.println();
11712        pw.println("  mHomeProcess: " + mHomeProcess);
11713        pw.println("  mPreviousProcess: " + mPreviousProcess);
11714        if (mHeavyWeightProcess != null) {
11715            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11716        }
11717
11718        return true;
11719    }
11720
11721    /**
11722     * There are three ways to call this:
11723     *  - no provider specified: dump all the providers
11724     *  - a flattened component name that matched an existing provider was specified as the
11725     *    first arg: dump that one provider
11726     *  - the first arg isn't the flattened component name of an existing provider:
11727     *    dump all providers whose component contains the first arg as a substring
11728     */
11729    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11730            int opti, boolean dumpAll) {
11731        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11732    }
11733
11734    static class ItemMatcher {
11735        ArrayList<ComponentName> components;
11736        ArrayList<String> strings;
11737        ArrayList<Integer> objects;
11738        boolean all;
11739
11740        ItemMatcher() {
11741            all = true;
11742        }
11743
11744        void build(String name) {
11745            ComponentName componentName = ComponentName.unflattenFromString(name);
11746            if (componentName != null) {
11747                if (components == null) {
11748                    components = new ArrayList<ComponentName>();
11749                }
11750                components.add(componentName);
11751                all = false;
11752            } else {
11753                int objectId = 0;
11754                // Not a '/' separated full component name; maybe an object ID?
11755                try {
11756                    objectId = Integer.parseInt(name, 16);
11757                    if (objects == null) {
11758                        objects = new ArrayList<Integer>();
11759                    }
11760                    objects.add(objectId);
11761                    all = false;
11762                } catch (RuntimeException e) {
11763                    // Not an integer; just do string match.
11764                    if (strings == null) {
11765                        strings = new ArrayList<String>();
11766                    }
11767                    strings.add(name);
11768                    all = false;
11769                }
11770            }
11771        }
11772
11773        int build(String[] args, int opti) {
11774            for (; opti<args.length; opti++) {
11775                String name = args[opti];
11776                if ("--".equals(name)) {
11777                    return opti+1;
11778                }
11779                build(name);
11780            }
11781            return opti;
11782        }
11783
11784        boolean match(Object object, ComponentName comp) {
11785            if (all) {
11786                return true;
11787            }
11788            if (components != null) {
11789                for (int i=0; i<components.size(); i++) {
11790                    if (components.get(i).equals(comp)) {
11791                        return true;
11792                    }
11793                }
11794            }
11795            if (objects != null) {
11796                for (int i=0; i<objects.size(); i++) {
11797                    if (System.identityHashCode(object) == objects.get(i)) {
11798                        return true;
11799                    }
11800                }
11801            }
11802            if (strings != null) {
11803                String flat = comp.flattenToString();
11804                for (int i=0; i<strings.size(); i++) {
11805                    if (flat.contains(strings.get(i))) {
11806                        return true;
11807                    }
11808                }
11809            }
11810            return false;
11811        }
11812    }
11813
11814    /**
11815     * There are three things that cmd can be:
11816     *  - a flattened component name that matches an existing activity
11817     *  - the cmd arg isn't the flattened component name of an existing activity:
11818     *    dump all activity whose component contains the cmd as a substring
11819     *  - A hex number of the ActivityRecord object instance.
11820     */
11821    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11822            int opti, boolean dumpAll) {
11823        ArrayList<ActivityRecord> activities;
11824
11825        synchronized (this) {
11826            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11827        }
11828
11829        if (activities.size() <= 0) {
11830            return false;
11831        }
11832
11833        String[] newArgs = new String[args.length - opti];
11834        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11835
11836        TaskRecord lastTask = null;
11837        boolean needSep = false;
11838        for (int i=activities.size()-1; i>=0; i--) {
11839            ActivityRecord r = activities.get(i);
11840            if (needSep) {
11841                pw.println();
11842            }
11843            needSep = true;
11844            synchronized (this) {
11845                if (lastTask != r.task) {
11846                    lastTask = r.task;
11847                    pw.print("TASK "); pw.print(lastTask.affinity);
11848                            pw.print(" id="); pw.println(lastTask.taskId);
11849                    if (dumpAll) {
11850                        lastTask.dump(pw, "  ");
11851                    }
11852                }
11853            }
11854            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11855        }
11856        return true;
11857    }
11858
11859    /**
11860     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11861     * there is a thread associated with the activity.
11862     */
11863    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11864            final ActivityRecord r, String[] args, boolean dumpAll) {
11865        String innerPrefix = prefix + "  ";
11866        synchronized (this) {
11867            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11868                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11869                    pw.print(" pid=");
11870                    if (r.app != null) pw.println(r.app.pid);
11871                    else pw.println("(not running)");
11872            if (dumpAll) {
11873                r.dump(pw, innerPrefix);
11874            }
11875        }
11876        if (r.app != null && r.app.thread != null) {
11877            // flush anything that is already in the PrintWriter since the thread is going
11878            // to write to the file descriptor directly
11879            pw.flush();
11880            try {
11881                TransferPipe tp = new TransferPipe();
11882                try {
11883                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11884                            r.appToken, innerPrefix, args);
11885                    tp.go(fd);
11886                } finally {
11887                    tp.kill();
11888                }
11889            } catch (IOException e) {
11890                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11891            } catch (RemoteException e) {
11892                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11893            }
11894        }
11895    }
11896
11897    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11898            int opti, boolean dumpAll, String dumpPackage) {
11899        boolean needSep = false;
11900        boolean onlyHistory = false;
11901        boolean printedAnything = false;
11902
11903        if ("history".equals(dumpPackage)) {
11904            if (opti < args.length && "-s".equals(args[opti])) {
11905                dumpAll = false;
11906            }
11907            onlyHistory = true;
11908            dumpPackage = null;
11909        }
11910
11911        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11912        if (!onlyHistory && dumpAll) {
11913            if (mRegisteredReceivers.size() > 0) {
11914                boolean printed = false;
11915                Iterator it = mRegisteredReceivers.values().iterator();
11916                while (it.hasNext()) {
11917                    ReceiverList r = (ReceiverList)it.next();
11918                    if (dumpPackage != null && (r.app == null ||
11919                            !dumpPackage.equals(r.app.info.packageName))) {
11920                        continue;
11921                    }
11922                    if (!printed) {
11923                        pw.println("  Registered Receivers:");
11924                        needSep = true;
11925                        printed = true;
11926                        printedAnything = true;
11927                    }
11928                    pw.print("  * "); pw.println(r);
11929                    r.dump(pw, "    ");
11930                }
11931            }
11932
11933            if (mReceiverResolver.dump(pw, needSep ?
11934                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11935                    "    ", dumpPackage, false)) {
11936                needSep = true;
11937                printedAnything = true;
11938            }
11939        }
11940
11941        for (BroadcastQueue q : mBroadcastQueues) {
11942            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11943            printedAnything |= needSep;
11944        }
11945
11946        needSep = true;
11947
11948        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11949            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11950                if (needSep) {
11951                    pw.println();
11952                }
11953                needSep = true;
11954                printedAnything = true;
11955                pw.print("  Sticky broadcasts for user ");
11956                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11957                StringBuilder sb = new StringBuilder(128);
11958                for (Map.Entry<String, ArrayList<Intent>> ent
11959                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11960                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11961                    if (dumpAll) {
11962                        pw.println(":");
11963                        ArrayList<Intent> intents = ent.getValue();
11964                        final int N = intents.size();
11965                        for (int i=0; i<N; i++) {
11966                            sb.setLength(0);
11967                            sb.append("    Intent: ");
11968                            intents.get(i).toShortString(sb, false, true, false, false);
11969                            pw.println(sb.toString());
11970                            Bundle bundle = intents.get(i).getExtras();
11971                            if (bundle != null) {
11972                                pw.print("      ");
11973                                pw.println(bundle.toString());
11974                            }
11975                        }
11976                    } else {
11977                        pw.println("");
11978                    }
11979                }
11980            }
11981        }
11982
11983        if (!onlyHistory && dumpAll) {
11984            pw.println();
11985            for (BroadcastQueue queue : mBroadcastQueues) {
11986                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11987                        + queue.mBroadcastsScheduled);
11988            }
11989            pw.println("  mHandler:");
11990            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11991            needSep = true;
11992            printedAnything = true;
11993        }
11994
11995        if (!printedAnything) {
11996            pw.println("  (nothing)");
11997        }
11998    }
11999
12000    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12001            int opti, boolean dumpAll, String dumpPackage) {
12002        boolean needSep;
12003        boolean printedAnything = false;
12004
12005        ItemMatcher matcher = new ItemMatcher();
12006        matcher.build(args, opti);
12007
12008        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12009
12010        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12011        printedAnything |= needSep;
12012
12013        if (mLaunchingProviders.size() > 0) {
12014            boolean printed = false;
12015            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12016                ContentProviderRecord r = mLaunchingProviders.get(i);
12017                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12018                    continue;
12019                }
12020                if (!printed) {
12021                    if (needSep) pw.println();
12022                    needSep = true;
12023                    pw.println("  Launching content providers:");
12024                    printed = true;
12025                    printedAnything = true;
12026                }
12027                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12028                        pw.println(r);
12029            }
12030        }
12031
12032        if (mGrantedUriPermissions.size() > 0) {
12033            boolean printed = false;
12034            int dumpUid = -2;
12035            if (dumpPackage != null) {
12036                try {
12037                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12038                } catch (NameNotFoundException e) {
12039                    dumpUid = -1;
12040                }
12041            }
12042            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12043                int uid = mGrantedUriPermissions.keyAt(i);
12044                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12045                    continue;
12046                }
12047                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12048                if (!printed) {
12049                    if (needSep) pw.println();
12050                    needSep = true;
12051                    pw.println("  Granted Uri Permissions:");
12052                    printed = true;
12053                    printedAnything = true;
12054                }
12055                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12056                for (UriPermission perm : perms.values()) {
12057                    pw.print("    "); pw.println(perm);
12058                    if (dumpAll) {
12059                        perm.dump(pw, "      ");
12060                    }
12061                }
12062            }
12063        }
12064
12065        if (!printedAnything) {
12066            pw.println("  (nothing)");
12067        }
12068    }
12069
12070    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12071            int opti, boolean dumpAll, String dumpPackage) {
12072        boolean printed = false;
12073
12074        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12075
12076        if (mIntentSenderRecords.size() > 0) {
12077            Iterator<WeakReference<PendingIntentRecord>> it
12078                    = mIntentSenderRecords.values().iterator();
12079            while (it.hasNext()) {
12080                WeakReference<PendingIntentRecord> ref = it.next();
12081                PendingIntentRecord rec = ref != null ? ref.get(): null;
12082                if (dumpPackage != null && (rec == null
12083                        || !dumpPackage.equals(rec.key.packageName))) {
12084                    continue;
12085                }
12086                printed = true;
12087                if (rec != null) {
12088                    pw.print("  * "); pw.println(rec);
12089                    if (dumpAll) {
12090                        rec.dump(pw, "    ");
12091                    }
12092                } else {
12093                    pw.print("  * "); pw.println(ref);
12094                }
12095            }
12096        }
12097
12098        if (!printed) {
12099            pw.println("  (nothing)");
12100        }
12101    }
12102
12103    private static final int dumpProcessList(PrintWriter pw,
12104            ActivityManagerService service, List list,
12105            String prefix, String normalLabel, String persistentLabel,
12106            String dumpPackage) {
12107        int numPers = 0;
12108        final int N = list.size()-1;
12109        for (int i=N; i>=0; i--) {
12110            ProcessRecord r = (ProcessRecord)list.get(i);
12111            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12112                continue;
12113            }
12114            pw.println(String.format("%s%s #%2d: %s",
12115                    prefix, (r.persistent ? persistentLabel : normalLabel),
12116                    i, r.toString()));
12117            if (r.persistent) {
12118                numPers++;
12119            }
12120        }
12121        return numPers;
12122    }
12123
12124    private static final boolean dumpProcessOomList(PrintWriter pw,
12125            ActivityManagerService service, List<ProcessRecord> origList,
12126            String prefix, String normalLabel, String persistentLabel,
12127            boolean inclDetails, String dumpPackage) {
12128
12129        ArrayList<Pair<ProcessRecord, Integer>> list
12130                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12131        for (int i=0; i<origList.size(); i++) {
12132            ProcessRecord r = origList.get(i);
12133            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12134                continue;
12135            }
12136            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12137        }
12138
12139        if (list.size() <= 0) {
12140            return false;
12141        }
12142
12143        Comparator<Pair<ProcessRecord, Integer>> comparator
12144                = new Comparator<Pair<ProcessRecord, Integer>>() {
12145            @Override
12146            public int compare(Pair<ProcessRecord, Integer> object1,
12147                    Pair<ProcessRecord, Integer> object2) {
12148                if (object1.first.setAdj != object2.first.setAdj) {
12149                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12150                }
12151                if (object1.second.intValue() != object2.second.intValue()) {
12152                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12153                }
12154                return 0;
12155            }
12156        };
12157
12158        Collections.sort(list, comparator);
12159
12160        final long curRealtime = SystemClock.elapsedRealtime();
12161        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12162        final long curUptime = SystemClock.uptimeMillis();
12163        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12164
12165        for (int i=list.size()-1; i>=0; i--) {
12166            ProcessRecord r = list.get(i).first;
12167            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12168            char schedGroup;
12169            switch (r.setSchedGroup) {
12170                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12171                    schedGroup = 'B';
12172                    break;
12173                case Process.THREAD_GROUP_DEFAULT:
12174                    schedGroup = 'F';
12175                    break;
12176                default:
12177                    schedGroup = '?';
12178                    break;
12179            }
12180            char foreground;
12181            if (r.foregroundActivities) {
12182                foreground = 'A';
12183            } else if (r.foregroundServices) {
12184                foreground = 'S';
12185            } else {
12186                foreground = ' ';
12187            }
12188            String procState = ProcessList.makeProcStateString(r.curProcState);
12189            pw.print(prefix);
12190            pw.print(r.persistent ? persistentLabel : normalLabel);
12191            pw.print(" #");
12192            int num = (origList.size()-1)-list.get(i).second;
12193            if (num < 10) pw.print(' ');
12194            pw.print(num);
12195            pw.print(": ");
12196            pw.print(oomAdj);
12197            pw.print(' ');
12198            pw.print(schedGroup);
12199            pw.print('/');
12200            pw.print(foreground);
12201            pw.print('/');
12202            pw.print(procState);
12203            pw.print(" trm:");
12204            if (r.trimMemoryLevel < 10) pw.print(' ');
12205            pw.print(r.trimMemoryLevel);
12206            pw.print(' ');
12207            pw.print(r.toShortString());
12208            pw.print(" (");
12209            pw.print(r.adjType);
12210            pw.println(')');
12211            if (r.adjSource != null || r.adjTarget != null) {
12212                pw.print(prefix);
12213                pw.print("    ");
12214                if (r.adjTarget instanceof ComponentName) {
12215                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12216                } else if (r.adjTarget != null) {
12217                    pw.print(r.adjTarget.toString());
12218                } else {
12219                    pw.print("{null}");
12220                }
12221                pw.print("<=");
12222                if (r.adjSource instanceof ProcessRecord) {
12223                    pw.print("Proc{");
12224                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12225                    pw.println("}");
12226                } else if (r.adjSource != null) {
12227                    pw.println(r.adjSource.toString());
12228                } else {
12229                    pw.println("{null}");
12230                }
12231            }
12232            if (inclDetails) {
12233                pw.print(prefix);
12234                pw.print("    ");
12235                pw.print("oom: max="); pw.print(r.maxAdj);
12236                pw.print(" curRaw="); pw.print(r.curRawAdj);
12237                pw.print(" setRaw="); pw.print(r.setRawAdj);
12238                pw.print(" cur="); pw.print(r.curAdj);
12239                pw.print(" set="); pw.println(r.setAdj);
12240                pw.print(prefix);
12241                pw.print("    ");
12242                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12243                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12244                pw.print(" lastPss="); pw.print(r.lastPss);
12245                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12246                pw.print(prefix);
12247                pw.print("    ");
12248                pw.print("keeping="); pw.print(r.keeping);
12249                pw.print(" cached="); pw.print(r.cached);
12250                pw.print(" empty="); pw.print(r.empty);
12251                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12252
12253                if (!r.keeping) {
12254                    if (r.lastWakeTime != 0) {
12255                        long wtime;
12256                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12257                        synchronized (stats) {
12258                            wtime = stats.getProcessWakeTime(r.info.uid,
12259                                    r.pid, curRealtime);
12260                        }
12261                        long timeUsed = wtime - r.lastWakeTime;
12262                        pw.print(prefix);
12263                        pw.print("    ");
12264                        pw.print("keep awake over ");
12265                        TimeUtils.formatDuration(realtimeSince, pw);
12266                        pw.print(" used ");
12267                        TimeUtils.formatDuration(timeUsed, pw);
12268                        pw.print(" (");
12269                        pw.print((timeUsed*100)/realtimeSince);
12270                        pw.println("%)");
12271                    }
12272                    if (r.lastCpuTime != 0) {
12273                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12274                        pw.print(prefix);
12275                        pw.print("    ");
12276                        pw.print("run cpu over ");
12277                        TimeUtils.formatDuration(uptimeSince, pw);
12278                        pw.print(" used ");
12279                        TimeUtils.formatDuration(timeUsed, pw);
12280                        pw.print(" (");
12281                        pw.print((timeUsed*100)/uptimeSince);
12282                        pw.println("%)");
12283                    }
12284                }
12285            }
12286        }
12287        return true;
12288    }
12289
12290    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12291        ArrayList<ProcessRecord> procs;
12292        synchronized (this) {
12293            if (args != null && args.length > start
12294                    && args[start].charAt(0) != '-') {
12295                procs = new ArrayList<ProcessRecord>();
12296                int pid = -1;
12297                try {
12298                    pid = Integer.parseInt(args[start]);
12299                } catch (NumberFormatException e) {
12300                }
12301                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12302                    ProcessRecord proc = mLruProcesses.get(i);
12303                    if (proc.pid == pid) {
12304                        procs.add(proc);
12305                    } else if (proc.processName.equals(args[start])) {
12306                        procs.add(proc);
12307                    }
12308                }
12309                if (procs.size() <= 0) {
12310                    return null;
12311                }
12312            } else {
12313                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12314            }
12315        }
12316        return procs;
12317    }
12318
12319    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12320            PrintWriter pw, String[] args) {
12321        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12322        if (procs == null) {
12323            pw.println("No process found for: " + args[0]);
12324            return;
12325        }
12326
12327        long uptime = SystemClock.uptimeMillis();
12328        long realtime = SystemClock.elapsedRealtime();
12329        pw.println("Applications Graphics Acceleration Info:");
12330        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12331
12332        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12333            ProcessRecord r = procs.get(i);
12334            if (r.thread != null) {
12335                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12336                pw.flush();
12337                try {
12338                    TransferPipe tp = new TransferPipe();
12339                    try {
12340                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12341                        tp.go(fd);
12342                    } finally {
12343                        tp.kill();
12344                    }
12345                } catch (IOException e) {
12346                    pw.println("Failure while dumping the app: " + r);
12347                    pw.flush();
12348                } catch (RemoteException e) {
12349                    pw.println("Got a RemoteException while dumping the app " + r);
12350                    pw.flush();
12351                }
12352            }
12353        }
12354    }
12355
12356    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12357        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12358        if (procs == null) {
12359            pw.println("No process found for: " + args[0]);
12360            return;
12361        }
12362
12363        pw.println("Applications Database Info:");
12364
12365        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12366            ProcessRecord r = procs.get(i);
12367            if (r.thread != null) {
12368                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12369                pw.flush();
12370                try {
12371                    TransferPipe tp = new TransferPipe();
12372                    try {
12373                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12374                        tp.go(fd);
12375                    } finally {
12376                        tp.kill();
12377                    }
12378                } catch (IOException e) {
12379                    pw.println("Failure while dumping the app: " + r);
12380                    pw.flush();
12381                } catch (RemoteException e) {
12382                    pw.println("Got a RemoteException while dumping the app " + r);
12383                    pw.flush();
12384                }
12385            }
12386        }
12387    }
12388
12389    final static class MemItem {
12390        final boolean isProc;
12391        final String label;
12392        final String shortLabel;
12393        final long pss;
12394        final int id;
12395        final boolean hasActivities;
12396        ArrayList<MemItem> subitems;
12397
12398        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12399                boolean _hasActivities) {
12400            isProc = true;
12401            label = _label;
12402            shortLabel = _shortLabel;
12403            pss = _pss;
12404            id = _id;
12405            hasActivities = _hasActivities;
12406        }
12407
12408        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12409            isProc = false;
12410            label = _label;
12411            shortLabel = _shortLabel;
12412            pss = _pss;
12413            id = _id;
12414            hasActivities = false;
12415        }
12416    }
12417
12418    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12419            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12420        if (sort && !isCompact) {
12421            Collections.sort(items, new Comparator<MemItem>() {
12422                @Override
12423                public int compare(MemItem lhs, MemItem rhs) {
12424                    if (lhs.pss < rhs.pss) {
12425                        return 1;
12426                    } else if (lhs.pss > rhs.pss) {
12427                        return -1;
12428                    }
12429                    return 0;
12430                }
12431            });
12432        }
12433
12434        for (int i=0; i<items.size(); i++) {
12435            MemItem mi = items.get(i);
12436            if (!isCompact) {
12437                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12438            } else if (mi.isProc) {
12439                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12440                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12441                pw.println(mi.hasActivities ? ",a" : ",e");
12442            } else {
12443                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12444                pw.println(mi.pss);
12445            }
12446            if (mi.subitems != null) {
12447                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12448                        true, isCompact);
12449            }
12450        }
12451    }
12452
12453    // These are in KB.
12454    static final long[] DUMP_MEM_BUCKETS = new long[] {
12455        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12456        120*1024, 160*1024, 200*1024,
12457        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12458        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12459    };
12460
12461    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12462            boolean stackLike) {
12463        int start = label.lastIndexOf('.');
12464        if (start >= 0) start++;
12465        else start = 0;
12466        int end = label.length();
12467        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12468            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12469                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12470                out.append(bucket);
12471                out.append(stackLike ? "MB." : "MB ");
12472                out.append(label, start, end);
12473                return;
12474            }
12475        }
12476        out.append(memKB/1024);
12477        out.append(stackLike ? "MB." : "MB ");
12478        out.append(label, start, end);
12479    }
12480
12481    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12482            ProcessList.NATIVE_ADJ,
12483            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12484            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12485            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12486            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12487            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12488    };
12489    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12490            "Native",
12491            "System", "Persistent", "Foreground",
12492            "Visible", "Perceptible",
12493            "Heavy Weight", "Backup",
12494            "A Services", "Home",
12495            "Previous", "B Services", "Cached"
12496    };
12497    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12498            "native",
12499            "sys", "pers", "fore",
12500            "vis", "percept",
12501            "heavy", "backup",
12502            "servicea", "home",
12503            "prev", "serviceb", "cached"
12504    };
12505
12506    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12507            long realtime, boolean isCheckinRequest, boolean isCompact) {
12508        if (isCheckinRequest || isCompact) {
12509            // short checkin version
12510            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12511        } else {
12512            pw.println("Applications Memory Usage (kB):");
12513            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12514        }
12515    }
12516
12517    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12518            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12519        boolean dumpDetails = false;
12520        boolean dumpFullDetails = false;
12521        boolean dumpDalvik = false;
12522        boolean oomOnly = false;
12523        boolean isCompact = false;
12524        boolean localOnly = false;
12525
12526        int opti = 0;
12527        while (opti < args.length) {
12528            String opt = args[opti];
12529            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12530                break;
12531            }
12532            opti++;
12533            if ("-a".equals(opt)) {
12534                dumpDetails = true;
12535                dumpFullDetails = true;
12536                dumpDalvik = true;
12537            } else if ("-d".equals(opt)) {
12538                dumpDalvik = true;
12539            } else if ("-c".equals(opt)) {
12540                isCompact = true;
12541            } else if ("--oom".equals(opt)) {
12542                oomOnly = true;
12543            } else if ("--local".equals(opt)) {
12544                localOnly = true;
12545            } else if ("-h".equals(opt)) {
12546                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12547                pw.println("  -a: include all available information for each process.");
12548                pw.println("  -d: include dalvik details when dumping process details.");
12549                pw.println("  -c: dump in a compact machine-parseable representation.");
12550                pw.println("  --oom: only show processes organized by oom adj.");
12551                pw.println("  --local: only collect details locally, don't call process.");
12552                pw.println("If [process] is specified it can be the name or ");
12553                pw.println("pid of a specific process to dump.");
12554                return;
12555            } else {
12556                pw.println("Unknown argument: " + opt + "; use -h for help");
12557            }
12558        }
12559
12560        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12561        long uptime = SystemClock.uptimeMillis();
12562        long realtime = SystemClock.elapsedRealtime();
12563        final long[] tmpLong = new long[1];
12564
12565        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12566        if (procs == null) {
12567            // No Java processes.  Maybe they want to print a native process.
12568            if (args != null && args.length > opti
12569                    && args[opti].charAt(0) != '-') {
12570                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12571                        = new ArrayList<ProcessCpuTracker.Stats>();
12572                updateCpuStatsNow();
12573                int findPid = -1;
12574                try {
12575                    findPid = Integer.parseInt(args[opti]);
12576                } catch (NumberFormatException e) {
12577                }
12578                synchronized (mProcessCpuThread) {
12579                    final int N = mProcessCpuTracker.countStats();
12580                    for (int i=0; i<N; i++) {
12581                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12582                        if (st.pid == findPid || (st.baseName != null
12583                                && st.baseName.equals(args[opti]))) {
12584                            nativeProcs.add(st);
12585                        }
12586                    }
12587                }
12588                if (nativeProcs.size() > 0) {
12589                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12590                            isCompact);
12591                    Debug.MemoryInfo mi = null;
12592                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12593                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12594                        final int pid = r.pid;
12595                        if (!isCheckinRequest && dumpDetails) {
12596                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12597                        }
12598                        if (mi == null) {
12599                            mi = new Debug.MemoryInfo();
12600                        }
12601                        if (dumpDetails || (!brief && !oomOnly)) {
12602                            Debug.getMemoryInfo(pid, mi);
12603                        } else {
12604                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12605                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12606                        }
12607                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12608                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12609                        if (isCheckinRequest) {
12610                            pw.println();
12611                        }
12612                    }
12613                    return;
12614                }
12615            }
12616            pw.println("No process found for: " + args[opti]);
12617            return;
12618        }
12619
12620        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12621            dumpDetails = true;
12622        }
12623
12624        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12625
12626        String[] innerArgs = new String[args.length-opti];
12627        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12628
12629        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12630        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12631        long nativePss=0, dalvikPss=0, otherPss=0;
12632        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12633
12634        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12635        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12636                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12637
12638        long totalPss = 0;
12639        long cachedPss = 0;
12640
12641        Debug.MemoryInfo mi = null;
12642        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12643            final ProcessRecord r = procs.get(i);
12644            final IApplicationThread thread;
12645            final int pid;
12646            final int oomAdj;
12647            final boolean hasActivities;
12648            synchronized (this) {
12649                thread = r.thread;
12650                pid = r.pid;
12651                oomAdj = r.getSetAdjWithServices();
12652                hasActivities = r.activities.size() > 0;
12653            }
12654            if (thread != null) {
12655                if (!isCheckinRequest && dumpDetails) {
12656                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12657                }
12658                if (mi == null) {
12659                    mi = new Debug.MemoryInfo();
12660                }
12661                if (dumpDetails || (!brief && !oomOnly)) {
12662                    Debug.getMemoryInfo(pid, mi);
12663                } else {
12664                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12665                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12666                }
12667                if (dumpDetails) {
12668                    if (localOnly) {
12669                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12670                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12671                        if (isCheckinRequest) {
12672                            pw.println();
12673                        }
12674                    } else {
12675                        try {
12676                            pw.flush();
12677                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12678                                    dumpDalvik, innerArgs);
12679                        } catch (RemoteException e) {
12680                            if (!isCheckinRequest) {
12681                                pw.println("Got RemoteException!");
12682                                pw.flush();
12683                            }
12684                        }
12685                    }
12686                }
12687
12688                final long myTotalPss = mi.getTotalPss();
12689                final long myTotalUss = mi.getTotalUss();
12690
12691                synchronized (this) {
12692                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12693                        // Record this for posterity if the process has been stable.
12694                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12695                    }
12696                }
12697
12698                if (!isCheckinRequest && mi != null) {
12699                    totalPss += myTotalPss;
12700                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12701                            (hasActivities ? " / activities)" : ")"),
12702                            r.processName, myTotalPss, pid, hasActivities);
12703                    procMems.add(pssItem);
12704                    procMemsMap.put(pid, pssItem);
12705
12706                    nativePss += mi.nativePss;
12707                    dalvikPss += mi.dalvikPss;
12708                    otherPss += mi.otherPss;
12709                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12710                        long mem = mi.getOtherPss(j);
12711                        miscPss[j] += mem;
12712                        otherPss -= mem;
12713                    }
12714
12715                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12716                        cachedPss += myTotalPss;
12717                    }
12718
12719                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12720                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12721                                || oomIndex == (oomPss.length-1)) {
12722                            oomPss[oomIndex] += myTotalPss;
12723                            if (oomProcs[oomIndex] == null) {
12724                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12725                            }
12726                            oomProcs[oomIndex].add(pssItem);
12727                            break;
12728                        }
12729                    }
12730                }
12731            }
12732        }
12733
12734        long nativeProcTotalPss = 0;
12735
12736        if (!isCheckinRequest && procs.size() > 1) {
12737            // If we are showing aggregations, also look for native processes to
12738            // include so that our aggregations are more accurate.
12739            updateCpuStatsNow();
12740            synchronized (mProcessCpuThread) {
12741                final int N = mProcessCpuTracker.countStats();
12742                for (int i=0; i<N; i++) {
12743                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12744                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12745                        if (mi == null) {
12746                            mi = new Debug.MemoryInfo();
12747                        }
12748                        if (!brief && !oomOnly) {
12749                            Debug.getMemoryInfo(st.pid, mi);
12750                        } else {
12751                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12752                            mi.nativePrivateDirty = (int)tmpLong[0];
12753                        }
12754
12755                        final long myTotalPss = mi.getTotalPss();
12756                        totalPss += myTotalPss;
12757                        nativeProcTotalPss += myTotalPss;
12758
12759                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12760                                st.name, myTotalPss, st.pid, false);
12761                        procMems.add(pssItem);
12762
12763                        nativePss += mi.nativePss;
12764                        dalvikPss += mi.dalvikPss;
12765                        otherPss += mi.otherPss;
12766                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12767                            long mem = mi.getOtherPss(j);
12768                            miscPss[j] += mem;
12769                            otherPss -= mem;
12770                        }
12771                        oomPss[0] += myTotalPss;
12772                        if (oomProcs[0] == null) {
12773                            oomProcs[0] = new ArrayList<MemItem>();
12774                        }
12775                        oomProcs[0].add(pssItem);
12776                    }
12777                }
12778            }
12779
12780            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12781
12782            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12783            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12784            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12785            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12786                String label = Debug.MemoryInfo.getOtherLabel(j);
12787                catMems.add(new MemItem(label, label, miscPss[j], j));
12788            }
12789
12790            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12791            for (int j=0; j<oomPss.length; j++) {
12792                if (oomPss[j] != 0) {
12793                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12794                            : DUMP_MEM_OOM_LABEL[j];
12795                    MemItem item = new MemItem(label, label, oomPss[j],
12796                            DUMP_MEM_OOM_ADJ[j]);
12797                    item.subitems = oomProcs[j];
12798                    oomMems.add(item);
12799                }
12800            }
12801
12802            if (!brief && !oomOnly && !isCompact) {
12803                pw.println();
12804                pw.println("Total PSS by process:");
12805                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12806                pw.println();
12807            }
12808            if (!isCompact) {
12809                pw.println("Total PSS by OOM adjustment:");
12810            }
12811            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12812            if (!brief && !oomOnly) {
12813                PrintWriter out = categoryPw != null ? categoryPw : pw;
12814                if (!isCompact) {
12815                    out.println();
12816                    out.println("Total PSS by category:");
12817                }
12818                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12819            }
12820            if (!isCompact) {
12821                pw.println();
12822            }
12823            MemInfoReader memInfo = new MemInfoReader();
12824            memInfo.readMemInfo();
12825            if (nativeProcTotalPss > 0) {
12826                synchronized (this) {
12827                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12828                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12829                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12830                            nativeProcTotalPss);
12831                }
12832            }
12833            if (!brief) {
12834                if (!isCompact) {
12835                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12836                    pw.print(" kB (status ");
12837                    switch (mLastMemoryLevel) {
12838                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12839                            pw.println("normal)");
12840                            break;
12841                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12842                            pw.println("moderate)");
12843                            break;
12844                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12845                            pw.println("low)");
12846                            break;
12847                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12848                            pw.println("critical)");
12849                            break;
12850                        default:
12851                            pw.print(mLastMemoryLevel);
12852                            pw.println(")");
12853                            break;
12854                    }
12855                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12856                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12857                            pw.print(cachedPss); pw.print(" cached pss + ");
12858                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12859                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12860                } else {
12861                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12862                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12863                            + memInfo.getFreeSizeKb()); pw.print(",");
12864                    pw.println(totalPss - cachedPss);
12865                }
12866            }
12867            if (!isCompact) {
12868                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12869                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12870                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12871                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12872                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12873                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12874                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12875                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12876                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12877                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12878                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12879            }
12880            if (!brief) {
12881                if (memInfo.getZramTotalSizeKb() != 0) {
12882                    if (!isCompact) {
12883                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12884                                pw.print(" kB physical used for ");
12885                                pw.print(memInfo.getSwapTotalSizeKb()
12886                                        - memInfo.getSwapFreeSizeKb());
12887                                pw.print(" kB in swap (");
12888                                pw.print(memInfo.getSwapTotalSizeKb());
12889                                pw.println(" kB total swap)");
12890                    } else {
12891                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12892                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12893                                pw.println(memInfo.getSwapFreeSizeKb());
12894                    }
12895                }
12896                final int[] SINGLE_LONG_FORMAT = new int[] {
12897                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12898                };
12899                long[] longOut = new long[1];
12900                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12901                        SINGLE_LONG_FORMAT, null, longOut, null);
12902                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12903                longOut[0] = 0;
12904                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12905                        SINGLE_LONG_FORMAT, null, longOut, null);
12906                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12907                longOut[0] = 0;
12908                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12909                        SINGLE_LONG_FORMAT, null, longOut, null);
12910                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12911                longOut[0] = 0;
12912                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12913                        SINGLE_LONG_FORMAT, null, longOut, null);
12914                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12915                if (!isCompact) {
12916                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12917                        pw.print("      KSM: "); pw.print(sharing);
12918                                pw.print(" kB saved from shared ");
12919                                pw.print(shared); pw.println(" kB");
12920                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12921                                pw.print(voltile); pw.println(" kB volatile");
12922                    }
12923                    pw.print("   Tuning: ");
12924                    pw.print(ActivityManager.staticGetMemoryClass());
12925                    pw.print(" (large ");
12926                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12927                    pw.print("), oom ");
12928                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12929                    pw.print(" kB");
12930                    pw.print(", restore limit ");
12931                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12932                    pw.print(" kB");
12933                    if (ActivityManager.isLowRamDeviceStatic()) {
12934                        pw.print(" (low-ram)");
12935                    }
12936                    if (ActivityManager.isHighEndGfx()) {
12937                        pw.print(" (high-end-gfx)");
12938                    }
12939                    pw.println();
12940                } else {
12941                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12942                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12943                    pw.println(voltile);
12944                    pw.print("tuning,");
12945                    pw.print(ActivityManager.staticGetMemoryClass());
12946                    pw.print(',');
12947                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12948                    pw.print(',');
12949                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12950                    if (ActivityManager.isLowRamDeviceStatic()) {
12951                        pw.print(",low-ram");
12952                    }
12953                    if (ActivityManager.isHighEndGfx()) {
12954                        pw.print(",high-end-gfx");
12955                    }
12956                    pw.println();
12957                }
12958            }
12959        }
12960    }
12961
12962    /**
12963     * Searches array of arguments for the specified string
12964     * @param args array of argument strings
12965     * @param value value to search for
12966     * @return true if the value is contained in the array
12967     */
12968    private static boolean scanArgs(String[] args, String value) {
12969        if (args != null) {
12970            for (String arg : args) {
12971                if (value.equals(arg)) {
12972                    return true;
12973                }
12974            }
12975        }
12976        return false;
12977    }
12978
12979    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12980            ContentProviderRecord cpr, boolean always) {
12981        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12982
12983        if (!inLaunching || always) {
12984            synchronized (cpr) {
12985                cpr.launchingApp = null;
12986                cpr.notifyAll();
12987            }
12988            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12989            String names[] = cpr.info.authority.split(";");
12990            for (int j = 0; j < names.length; j++) {
12991                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12992            }
12993        }
12994
12995        for (int i=0; i<cpr.connections.size(); i++) {
12996            ContentProviderConnection conn = cpr.connections.get(i);
12997            if (conn.waiting) {
12998                // If this connection is waiting for the provider, then we don't
12999                // need to mess with its process unless we are always removing
13000                // or for some reason the provider is not currently launching.
13001                if (inLaunching && !always) {
13002                    continue;
13003                }
13004            }
13005            ProcessRecord capp = conn.client;
13006            conn.dead = true;
13007            if (conn.stableCount > 0) {
13008                if (!capp.persistent && capp.thread != null
13009                        && capp.pid != 0
13010                        && capp.pid != MY_PID) {
13011                    killUnneededProcessLocked(capp, "depends on provider "
13012                            + cpr.name.flattenToShortString()
13013                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13014                }
13015            } else if (capp.thread != null && conn.provider.provider != null) {
13016                try {
13017                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13018                } catch (RemoteException e) {
13019                }
13020                // In the protocol here, we don't expect the client to correctly
13021                // clean up this connection, we'll just remove it.
13022                cpr.connections.remove(i);
13023                conn.client.conProviders.remove(conn);
13024            }
13025        }
13026
13027        if (inLaunching && always) {
13028            mLaunchingProviders.remove(cpr);
13029        }
13030        return inLaunching;
13031    }
13032
13033    /**
13034     * Main code for cleaning up a process when it has gone away.  This is
13035     * called both as a result of the process dying, or directly when stopping
13036     * a process when running in single process mode.
13037     */
13038    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13039            boolean restarting, boolean allowRestart, int index) {
13040        if (index >= 0) {
13041            removeLruProcessLocked(app);
13042            ProcessList.remove(app.pid);
13043        }
13044
13045        mProcessesToGc.remove(app);
13046        mPendingPssProcesses.remove(app);
13047
13048        // Dismiss any open dialogs.
13049        if (app.crashDialog != null && !app.forceCrashReport) {
13050            app.crashDialog.dismiss();
13051            app.crashDialog = null;
13052        }
13053        if (app.anrDialog != null) {
13054            app.anrDialog.dismiss();
13055            app.anrDialog = null;
13056        }
13057        if (app.waitDialog != null) {
13058            app.waitDialog.dismiss();
13059            app.waitDialog = null;
13060        }
13061
13062        app.crashing = false;
13063        app.notResponding = false;
13064
13065        app.resetPackageList(mProcessStats);
13066        app.unlinkDeathRecipient();
13067        app.makeInactive(mProcessStats);
13068        app.forcingToForeground = null;
13069        updateProcessForegroundLocked(app, false, false);
13070        app.foregroundActivities = false;
13071        app.hasShownUi = false;
13072        app.treatLikeActivity = false;
13073        app.hasAboveClient = false;
13074        app.hasClientActivities = false;
13075
13076        mServices.killServicesLocked(app, allowRestart);
13077
13078        boolean restart = false;
13079
13080        // Remove published content providers.
13081        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13082            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13083            final boolean always = app.bad || !allowRestart;
13084            if (removeDyingProviderLocked(app, cpr, always) || always) {
13085                // We left the provider in the launching list, need to
13086                // restart it.
13087                restart = true;
13088            }
13089
13090            cpr.provider = null;
13091            cpr.proc = null;
13092        }
13093        app.pubProviders.clear();
13094
13095        // Take care of any launching providers waiting for this process.
13096        if (checkAppInLaunchingProvidersLocked(app, false)) {
13097            restart = true;
13098        }
13099
13100        // Unregister from connected content providers.
13101        if (!app.conProviders.isEmpty()) {
13102            for (int i=0; i<app.conProviders.size(); i++) {
13103                ContentProviderConnection conn = app.conProviders.get(i);
13104                conn.provider.connections.remove(conn);
13105            }
13106            app.conProviders.clear();
13107        }
13108
13109        // At this point there may be remaining entries in mLaunchingProviders
13110        // where we were the only one waiting, so they are no longer of use.
13111        // Look for these and clean up if found.
13112        // XXX Commented out for now.  Trying to figure out a way to reproduce
13113        // the actual situation to identify what is actually going on.
13114        if (false) {
13115            for (int i=0; i<mLaunchingProviders.size(); i++) {
13116                ContentProviderRecord cpr = (ContentProviderRecord)
13117                        mLaunchingProviders.get(i);
13118                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13119                    synchronized (cpr) {
13120                        cpr.launchingApp = null;
13121                        cpr.notifyAll();
13122                    }
13123                }
13124            }
13125        }
13126
13127        skipCurrentReceiverLocked(app);
13128
13129        // Unregister any receivers.
13130        for (int i=app.receivers.size()-1; i>=0; i--) {
13131            removeReceiverLocked(app.receivers.valueAt(i));
13132        }
13133        app.receivers.clear();
13134
13135        // If the app is undergoing backup, tell the backup manager about it
13136        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13137            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13138                    + mBackupTarget.appInfo + " died during backup");
13139            try {
13140                IBackupManager bm = IBackupManager.Stub.asInterface(
13141                        ServiceManager.getService(Context.BACKUP_SERVICE));
13142                bm.agentDisconnected(app.info.packageName);
13143            } catch (RemoteException e) {
13144                // can't happen; backup manager is local
13145            }
13146        }
13147
13148        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13149            ProcessChangeItem item = mPendingProcessChanges.get(i);
13150            if (item.pid == app.pid) {
13151                mPendingProcessChanges.remove(i);
13152                mAvailProcessChanges.add(item);
13153            }
13154        }
13155        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13156
13157        // If the caller is restarting this app, then leave it in its
13158        // current lists and let the caller take care of it.
13159        if (restarting) {
13160            return;
13161        }
13162
13163        if (!app.persistent || app.isolated) {
13164            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13165                    "Removing non-persistent process during cleanup: " + app);
13166            mProcessNames.remove(app.processName, app.uid);
13167            mIsolatedProcesses.remove(app.uid);
13168            if (mHeavyWeightProcess == app) {
13169                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13170                        mHeavyWeightProcess.userId, 0));
13171                mHeavyWeightProcess = null;
13172            }
13173        } else if (!app.removed) {
13174            // This app is persistent, so we need to keep its record around.
13175            // If it is not already on the pending app list, add it there
13176            // and start a new process for it.
13177            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13178                mPersistentStartingProcesses.add(app);
13179                restart = true;
13180            }
13181        }
13182        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13183                "Clean-up removing on hold: " + app);
13184        mProcessesOnHold.remove(app);
13185
13186        if (app == mHomeProcess) {
13187            mHomeProcess = null;
13188        }
13189        if (app == mPreviousProcess) {
13190            mPreviousProcess = null;
13191        }
13192
13193        if (restart && !app.isolated) {
13194            // We have components that still need to be running in the
13195            // process, so re-launch it.
13196            mProcessNames.put(app.processName, app.uid, app);
13197            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13198        } else if (app.pid > 0 && app.pid != MY_PID) {
13199            // Goodbye!
13200            boolean removed;
13201            synchronized (mPidsSelfLocked) {
13202                mPidsSelfLocked.remove(app.pid);
13203                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13204            }
13205            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13206                    app.processName, app.info.uid);
13207            if (app.isolated) {
13208                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13209            }
13210            app.setPid(0);
13211        }
13212    }
13213
13214    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13215        // Look through the content providers we are waiting to have launched,
13216        // and if any run in this process then either schedule a restart of
13217        // the process or kill the client waiting for it if this process has
13218        // gone bad.
13219        int NL = mLaunchingProviders.size();
13220        boolean restart = false;
13221        for (int i=0; i<NL; i++) {
13222            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13223            if (cpr.launchingApp == app) {
13224                if (!alwaysBad && !app.bad) {
13225                    restart = true;
13226                } else {
13227                    removeDyingProviderLocked(app, cpr, true);
13228                    // cpr should have been removed from mLaunchingProviders
13229                    NL = mLaunchingProviders.size();
13230                    i--;
13231                }
13232            }
13233        }
13234        return restart;
13235    }
13236
13237    // =========================================================
13238    // SERVICES
13239    // =========================================================
13240
13241    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13242            int flags) {
13243        enforceNotIsolatedCaller("getServices");
13244        synchronized (this) {
13245            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13246        }
13247    }
13248
13249    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13250        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13251        synchronized (this) {
13252            return mServices.getRunningServiceControlPanelLocked(name);
13253        }
13254    }
13255
13256    public ComponentName startService(IApplicationThread caller, Intent service,
13257            String resolvedType, int userId) {
13258        enforceNotIsolatedCaller("startService");
13259        // Refuse possible leaked file descriptors
13260        if (service != null && service.hasFileDescriptors() == true) {
13261            throw new IllegalArgumentException("File descriptors passed in Intent");
13262        }
13263
13264        if (DEBUG_SERVICE)
13265            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13266        synchronized(this) {
13267            final int callingPid = Binder.getCallingPid();
13268            final int callingUid = Binder.getCallingUid();
13269            final long origId = Binder.clearCallingIdentity();
13270            ComponentName res = mServices.startServiceLocked(caller, service,
13271                    resolvedType, callingPid, callingUid, userId);
13272            Binder.restoreCallingIdentity(origId);
13273            return res;
13274        }
13275    }
13276
13277    ComponentName startServiceInPackage(int uid,
13278            Intent service, String resolvedType, int userId) {
13279        synchronized(this) {
13280            if (DEBUG_SERVICE)
13281                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13282            final long origId = Binder.clearCallingIdentity();
13283            ComponentName res = mServices.startServiceLocked(null, service,
13284                    resolvedType, -1, uid, userId);
13285            Binder.restoreCallingIdentity(origId);
13286            return res;
13287        }
13288    }
13289
13290    public int stopService(IApplicationThread caller, Intent service,
13291            String resolvedType, int userId) {
13292        enforceNotIsolatedCaller("stopService");
13293        // Refuse possible leaked file descriptors
13294        if (service != null && service.hasFileDescriptors() == true) {
13295            throw new IllegalArgumentException("File descriptors passed in Intent");
13296        }
13297
13298        synchronized(this) {
13299            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13300        }
13301    }
13302
13303    public IBinder peekService(Intent service, String resolvedType) {
13304        enforceNotIsolatedCaller("peekService");
13305        // Refuse possible leaked file descriptors
13306        if (service != null && service.hasFileDescriptors() == true) {
13307            throw new IllegalArgumentException("File descriptors passed in Intent");
13308        }
13309        synchronized(this) {
13310            return mServices.peekServiceLocked(service, resolvedType);
13311        }
13312    }
13313
13314    public boolean stopServiceToken(ComponentName className, IBinder token,
13315            int startId) {
13316        synchronized(this) {
13317            return mServices.stopServiceTokenLocked(className, token, startId);
13318        }
13319    }
13320
13321    public void setServiceForeground(ComponentName className, IBinder token,
13322            int id, Notification notification, boolean removeNotification) {
13323        synchronized(this) {
13324            mServices.setServiceForegroundLocked(className, token, id, notification,
13325                    removeNotification);
13326        }
13327    }
13328
13329    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13330            boolean requireFull, String name, String callerPackage) {
13331        final int callingUserId = UserHandle.getUserId(callingUid);
13332        if (callingUserId != userId) {
13333            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13334                if ((requireFull || checkComponentPermission(
13335                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13336                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13337                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13338                                callingPid, callingUid, -1, true)
13339                                != PackageManager.PERMISSION_GRANTED) {
13340                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13341                        // In this case, they would like to just execute as their
13342                        // owner user instead of failing.
13343                        userId = callingUserId;
13344                    } else {
13345                        StringBuilder builder = new StringBuilder(128);
13346                        builder.append("Permission Denial: ");
13347                        builder.append(name);
13348                        if (callerPackage != null) {
13349                            builder.append(" from ");
13350                            builder.append(callerPackage);
13351                        }
13352                        builder.append(" asks to run as user ");
13353                        builder.append(userId);
13354                        builder.append(" but is calling from user ");
13355                        builder.append(UserHandle.getUserId(callingUid));
13356                        builder.append("; this requires ");
13357                        builder.append(INTERACT_ACROSS_USERS_FULL);
13358                        if (!requireFull) {
13359                            builder.append(" or ");
13360                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13361                        }
13362                        String msg = builder.toString();
13363                        Slog.w(TAG, msg);
13364                        throw new SecurityException(msg);
13365                    }
13366                }
13367            }
13368            if (userId == UserHandle.USER_CURRENT
13369                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13370                // Note that we may be accessing this outside of a lock...
13371                // shouldn't be a big deal, if this is being called outside
13372                // of a locked context there is intrinsically a race with
13373                // the value the caller will receive and someone else changing it.
13374                userId = mCurrentUserId;
13375            }
13376            if (!allowAll && userId < 0) {
13377                throw new IllegalArgumentException(
13378                        "Call does not support special user #" + userId);
13379            }
13380        }
13381        return userId;
13382    }
13383
13384    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13385            String className, int flags) {
13386        boolean result = false;
13387        // For apps that don't have pre-defined UIDs, check for permission
13388        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13389            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13390                if (ActivityManager.checkUidPermission(
13391                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13392                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13393                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13394                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13395                            + " requests FLAG_SINGLE_USER, but app does not hold "
13396                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13397                    Slog.w(TAG, msg);
13398                    throw new SecurityException(msg);
13399                }
13400                // Permission passed
13401                result = true;
13402            }
13403        } else if ("system".equals(componentProcessName)) {
13404            result = true;
13405        } else {
13406            // App with pre-defined UID, check if it's a persistent app
13407            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13408        }
13409        if (DEBUG_MU) {
13410            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13411                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13412        }
13413        return result;
13414    }
13415
13416    /**
13417     * Checks to see if the caller is in the same app as the singleton
13418     * component, or the component is in a special app. It allows special apps
13419     * to export singleton components but prevents exporting singleton
13420     * components for regular apps.
13421     */
13422    boolean isValidSingletonCall(int callingUid, int componentUid) {
13423        int componentAppId = UserHandle.getAppId(componentUid);
13424        return UserHandle.isSameApp(callingUid, componentUid)
13425                || componentAppId == Process.SYSTEM_UID
13426                || componentAppId == Process.PHONE_UID
13427                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13428                        == PackageManager.PERMISSION_GRANTED;
13429    }
13430
13431    public int bindService(IApplicationThread caller, IBinder token,
13432            Intent service, String resolvedType,
13433            IServiceConnection connection, int flags, int userId) {
13434        enforceNotIsolatedCaller("bindService");
13435        // Refuse possible leaked file descriptors
13436        if (service != null && service.hasFileDescriptors() == true) {
13437            throw new IllegalArgumentException("File descriptors passed in Intent");
13438        }
13439
13440        synchronized(this) {
13441            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13442                    connection, flags, userId);
13443        }
13444    }
13445
13446    public boolean unbindService(IServiceConnection connection) {
13447        synchronized (this) {
13448            return mServices.unbindServiceLocked(connection);
13449        }
13450    }
13451
13452    public void publishService(IBinder token, Intent intent, IBinder service) {
13453        // Refuse possible leaked file descriptors
13454        if (intent != null && intent.hasFileDescriptors() == true) {
13455            throw new IllegalArgumentException("File descriptors passed in Intent");
13456        }
13457
13458        synchronized(this) {
13459            if (!(token instanceof ServiceRecord)) {
13460                throw new IllegalArgumentException("Invalid service token");
13461            }
13462            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13463        }
13464    }
13465
13466    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13467        // Refuse possible leaked file descriptors
13468        if (intent != null && intent.hasFileDescriptors() == true) {
13469            throw new IllegalArgumentException("File descriptors passed in Intent");
13470        }
13471
13472        synchronized(this) {
13473            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13474        }
13475    }
13476
13477    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13478        synchronized(this) {
13479            if (!(token instanceof ServiceRecord)) {
13480                throw new IllegalArgumentException("Invalid service token");
13481            }
13482            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13483        }
13484    }
13485
13486    // =========================================================
13487    // BACKUP AND RESTORE
13488    // =========================================================
13489
13490    // Cause the target app to be launched if necessary and its backup agent
13491    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13492    // activity manager to announce its creation.
13493    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13494        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13495        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13496
13497        synchronized(this) {
13498            // !!! TODO: currently no check here that we're already bound
13499            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13500            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13501            synchronized (stats) {
13502                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13503            }
13504
13505            // Backup agent is now in use, its package can't be stopped.
13506            try {
13507                AppGlobals.getPackageManager().setPackageStoppedState(
13508                        app.packageName, false, UserHandle.getUserId(app.uid));
13509            } catch (RemoteException e) {
13510            } catch (IllegalArgumentException e) {
13511                Slog.w(TAG, "Failed trying to unstop package "
13512                        + app.packageName + ": " + e);
13513            }
13514
13515            BackupRecord r = new BackupRecord(ss, app, backupMode);
13516            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13517                    ? new ComponentName(app.packageName, app.backupAgentName)
13518                    : new ComponentName("android", "FullBackupAgent");
13519            // startProcessLocked() returns existing proc's record if it's already running
13520            ProcessRecord proc = startProcessLocked(app.processName, app,
13521                    false, 0, "backup", hostingName, false, false, false);
13522            if (proc == null) {
13523                Slog.e(TAG, "Unable to start backup agent process " + r);
13524                return false;
13525            }
13526
13527            r.app = proc;
13528            mBackupTarget = r;
13529            mBackupAppName = app.packageName;
13530
13531            // Try not to kill the process during backup
13532            updateOomAdjLocked(proc);
13533
13534            // If the process is already attached, schedule the creation of the backup agent now.
13535            // If it is not yet live, this will be done when it attaches to the framework.
13536            if (proc.thread != null) {
13537                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13538                try {
13539                    proc.thread.scheduleCreateBackupAgent(app,
13540                            compatibilityInfoForPackageLocked(app), backupMode);
13541                } catch (RemoteException e) {
13542                    // Will time out on the backup manager side
13543                }
13544            } else {
13545                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13546            }
13547            // Invariants: at this point, the target app process exists and the application
13548            // is either already running or in the process of coming up.  mBackupTarget and
13549            // mBackupAppName describe the app, so that when it binds back to the AM we
13550            // know that it's scheduled for a backup-agent operation.
13551        }
13552
13553        return true;
13554    }
13555
13556    @Override
13557    public void clearPendingBackup() {
13558        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13559        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13560
13561        synchronized (this) {
13562            mBackupTarget = null;
13563            mBackupAppName = null;
13564        }
13565    }
13566
13567    // A backup agent has just come up
13568    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13569        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13570                + " = " + agent);
13571
13572        synchronized(this) {
13573            if (!agentPackageName.equals(mBackupAppName)) {
13574                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13575                return;
13576            }
13577        }
13578
13579        long oldIdent = Binder.clearCallingIdentity();
13580        try {
13581            IBackupManager bm = IBackupManager.Stub.asInterface(
13582                    ServiceManager.getService(Context.BACKUP_SERVICE));
13583            bm.agentConnected(agentPackageName, agent);
13584        } catch (RemoteException e) {
13585            // can't happen; the backup manager service is local
13586        } catch (Exception e) {
13587            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13588            e.printStackTrace();
13589        } finally {
13590            Binder.restoreCallingIdentity(oldIdent);
13591        }
13592    }
13593
13594    // done with this agent
13595    public void unbindBackupAgent(ApplicationInfo appInfo) {
13596        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13597        if (appInfo == null) {
13598            Slog.w(TAG, "unbind backup agent for null app");
13599            return;
13600        }
13601
13602        synchronized(this) {
13603            try {
13604                if (mBackupAppName == null) {
13605                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13606                    return;
13607                }
13608
13609                if (!mBackupAppName.equals(appInfo.packageName)) {
13610                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13611                    return;
13612                }
13613
13614                // Not backing this app up any more; reset its OOM adjustment
13615                final ProcessRecord proc = mBackupTarget.app;
13616                updateOomAdjLocked(proc);
13617
13618                // If the app crashed during backup, 'thread' will be null here
13619                if (proc.thread != null) {
13620                    try {
13621                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13622                                compatibilityInfoForPackageLocked(appInfo));
13623                    } catch (Exception e) {
13624                        Slog.e(TAG, "Exception when unbinding backup agent:");
13625                        e.printStackTrace();
13626                    }
13627                }
13628            } finally {
13629                mBackupTarget = null;
13630                mBackupAppName = null;
13631            }
13632        }
13633    }
13634    // =========================================================
13635    // BROADCASTS
13636    // =========================================================
13637
13638    private final List getStickiesLocked(String action, IntentFilter filter,
13639            List cur, int userId) {
13640        final ContentResolver resolver = mContext.getContentResolver();
13641        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13642        if (stickies == null) {
13643            return cur;
13644        }
13645        final ArrayList<Intent> list = stickies.get(action);
13646        if (list == null) {
13647            return cur;
13648        }
13649        int N = list.size();
13650        for (int i=0; i<N; i++) {
13651            Intent intent = list.get(i);
13652            if (filter.match(resolver, intent, true, TAG) >= 0) {
13653                if (cur == null) {
13654                    cur = new ArrayList<Intent>();
13655                }
13656                cur.add(intent);
13657            }
13658        }
13659        return cur;
13660    }
13661
13662    boolean isPendingBroadcastProcessLocked(int pid) {
13663        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13664                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13665    }
13666
13667    void skipPendingBroadcastLocked(int pid) {
13668            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13669            for (BroadcastQueue queue : mBroadcastQueues) {
13670                queue.skipPendingBroadcastLocked(pid);
13671            }
13672    }
13673
13674    // The app just attached; send any pending broadcasts that it should receive
13675    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13676        boolean didSomething = false;
13677        for (BroadcastQueue queue : mBroadcastQueues) {
13678            didSomething |= queue.sendPendingBroadcastsLocked(app);
13679        }
13680        return didSomething;
13681    }
13682
13683    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13684            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13685        enforceNotIsolatedCaller("registerReceiver");
13686        int callingUid;
13687        int callingPid;
13688        synchronized(this) {
13689            ProcessRecord callerApp = null;
13690            if (caller != null) {
13691                callerApp = getRecordForAppLocked(caller);
13692                if (callerApp == null) {
13693                    throw new SecurityException(
13694                            "Unable to find app for caller " + caller
13695                            + " (pid=" + Binder.getCallingPid()
13696                            + ") when registering receiver " + receiver);
13697                }
13698                if (callerApp.info.uid != Process.SYSTEM_UID &&
13699                        !callerApp.pkgList.containsKey(callerPackage) &&
13700                        !"android".equals(callerPackage)) {
13701                    throw new SecurityException("Given caller package " + callerPackage
13702                            + " is not running in process " + callerApp);
13703                }
13704                callingUid = callerApp.info.uid;
13705                callingPid = callerApp.pid;
13706            } else {
13707                callerPackage = null;
13708                callingUid = Binder.getCallingUid();
13709                callingPid = Binder.getCallingPid();
13710            }
13711
13712            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13713                    true, true, "registerReceiver", callerPackage);
13714
13715            List allSticky = null;
13716
13717            // Look for any matching sticky broadcasts...
13718            Iterator actions = filter.actionsIterator();
13719            if (actions != null) {
13720                while (actions.hasNext()) {
13721                    String action = (String)actions.next();
13722                    allSticky = getStickiesLocked(action, filter, allSticky,
13723                            UserHandle.USER_ALL);
13724                    allSticky = getStickiesLocked(action, filter, allSticky,
13725                            UserHandle.getUserId(callingUid));
13726                }
13727            } else {
13728                allSticky = getStickiesLocked(null, filter, allSticky,
13729                        UserHandle.USER_ALL);
13730                allSticky = getStickiesLocked(null, filter, allSticky,
13731                        UserHandle.getUserId(callingUid));
13732            }
13733
13734            // The first sticky in the list is returned directly back to
13735            // the client.
13736            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13737
13738            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13739                    + ": " + sticky);
13740
13741            if (receiver == null) {
13742                return sticky;
13743            }
13744
13745            ReceiverList rl
13746                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13747            if (rl == null) {
13748                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13749                        userId, receiver);
13750                if (rl.app != null) {
13751                    rl.app.receivers.add(rl);
13752                } else {
13753                    try {
13754                        receiver.asBinder().linkToDeath(rl, 0);
13755                    } catch (RemoteException e) {
13756                        return sticky;
13757                    }
13758                    rl.linkedToDeath = true;
13759                }
13760                mRegisteredReceivers.put(receiver.asBinder(), rl);
13761            } else if (rl.uid != callingUid) {
13762                throw new IllegalArgumentException(
13763                        "Receiver requested to register for uid " + callingUid
13764                        + " was previously registered for uid " + rl.uid);
13765            } else if (rl.pid != callingPid) {
13766                throw new IllegalArgumentException(
13767                        "Receiver requested to register for pid " + callingPid
13768                        + " was previously registered for pid " + rl.pid);
13769            } else if (rl.userId != userId) {
13770                throw new IllegalArgumentException(
13771                        "Receiver requested to register for user " + userId
13772                        + " was previously registered for user " + rl.userId);
13773            }
13774            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13775                    permission, callingUid, userId);
13776            rl.add(bf);
13777            if (!bf.debugCheck()) {
13778                Slog.w(TAG, "==> For Dynamic broadast");
13779            }
13780            mReceiverResolver.addFilter(bf);
13781
13782            // Enqueue broadcasts for all existing stickies that match
13783            // this filter.
13784            if (allSticky != null) {
13785                ArrayList receivers = new ArrayList();
13786                receivers.add(bf);
13787
13788                int N = allSticky.size();
13789                for (int i=0; i<N; i++) {
13790                    Intent intent = (Intent)allSticky.get(i);
13791                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13792                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13793                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13794                            null, null, false, true, true, -1);
13795                    queue.enqueueParallelBroadcastLocked(r);
13796                    queue.scheduleBroadcastsLocked();
13797                }
13798            }
13799
13800            return sticky;
13801        }
13802    }
13803
13804    public void unregisterReceiver(IIntentReceiver receiver) {
13805        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13806
13807        final long origId = Binder.clearCallingIdentity();
13808        try {
13809            boolean doTrim = false;
13810
13811            synchronized(this) {
13812                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13813                if (rl != null) {
13814                    if (rl.curBroadcast != null) {
13815                        BroadcastRecord r = rl.curBroadcast;
13816                        final boolean doNext = finishReceiverLocked(
13817                                receiver.asBinder(), r.resultCode, r.resultData,
13818                                r.resultExtras, r.resultAbort);
13819                        if (doNext) {
13820                            doTrim = true;
13821                            r.queue.processNextBroadcast(false);
13822                        }
13823                    }
13824
13825                    if (rl.app != null) {
13826                        rl.app.receivers.remove(rl);
13827                    }
13828                    removeReceiverLocked(rl);
13829                    if (rl.linkedToDeath) {
13830                        rl.linkedToDeath = false;
13831                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13832                    }
13833                }
13834            }
13835
13836            // If we actually concluded any broadcasts, we might now be able
13837            // to trim the recipients' apps from our working set
13838            if (doTrim) {
13839                trimApplications();
13840                return;
13841            }
13842
13843        } finally {
13844            Binder.restoreCallingIdentity(origId);
13845        }
13846    }
13847
13848    void removeReceiverLocked(ReceiverList rl) {
13849        mRegisteredReceivers.remove(rl.receiver.asBinder());
13850        int N = rl.size();
13851        for (int i=0; i<N; i++) {
13852            mReceiverResolver.removeFilter(rl.get(i));
13853        }
13854    }
13855
13856    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13857        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13858            ProcessRecord r = mLruProcesses.get(i);
13859            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13860                try {
13861                    r.thread.dispatchPackageBroadcast(cmd, packages);
13862                } catch (RemoteException ex) {
13863                }
13864            }
13865        }
13866    }
13867
13868    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13869            int[] users) {
13870        List<ResolveInfo> receivers = null;
13871        try {
13872            HashSet<ComponentName> singleUserReceivers = null;
13873            boolean scannedFirstReceivers = false;
13874            for (int user : users) {
13875                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13876                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13877                if (user != 0 && newReceivers != null) {
13878                    // If this is not the primary user, we need to check for
13879                    // any receivers that should be filtered out.
13880                    for (int i=0; i<newReceivers.size(); i++) {
13881                        ResolveInfo ri = newReceivers.get(i);
13882                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13883                            newReceivers.remove(i);
13884                            i--;
13885                        }
13886                    }
13887                }
13888                if (newReceivers != null && newReceivers.size() == 0) {
13889                    newReceivers = null;
13890                }
13891                if (receivers == null) {
13892                    receivers = newReceivers;
13893                } else if (newReceivers != null) {
13894                    // We need to concatenate the additional receivers
13895                    // found with what we have do far.  This would be easy,
13896                    // but we also need to de-dup any receivers that are
13897                    // singleUser.
13898                    if (!scannedFirstReceivers) {
13899                        // Collect any single user receivers we had already retrieved.
13900                        scannedFirstReceivers = true;
13901                        for (int i=0; i<receivers.size(); i++) {
13902                            ResolveInfo ri = receivers.get(i);
13903                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13904                                ComponentName cn = new ComponentName(
13905                                        ri.activityInfo.packageName, ri.activityInfo.name);
13906                                if (singleUserReceivers == null) {
13907                                    singleUserReceivers = new HashSet<ComponentName>();
13908                                }
13909                                singleUserReceivers.add(cn);
13910                            }
13911                        }
13912                    }
13913                    // Add the new results to the existing results, tracking
13914                    // and de-dupping single user receivers.
13915                    for (int i=0; i<newReceivers.size(); i++) {
13916                        ResolveInfo ri = newReceivers.get(i);
13917                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13918                            ComponentName cn = new ComponentName(
13919                                    ri.activityInfo.packageName, ri.activityInfo.name);
13920                            if (singleUserReceivers == null) {
13921                                singleUserReceivers = new HashSet<ComponentName>();
13922                            }
13923                            if (!singleUserReceivers.contains(cn)) {
13924                                singleUserReceivers.add(cn);
13925                                receivers.add(ri);
13926                            }
13927                        } else {
13928                            receivers.add(ri);
13929                        }
13930                    }
13931                }
13932            }
13933        } catch (RemoteException ex) {
13934            // pm is in same process, this will never happen.
13935        }
13936        return receivers;
13937    }
13938
13939    private final int broadcastIntentLocked(ProcessRecord callerApp,
13940            String callerPackage, Intent intent, String resolvedType,
13941            IIntentReceiver resultTo, int resultCode, String resultData,
13942            Bundle map, String requiredPermission, int appOp,
13943            boolean ordered, boolean sticky, int callingPid, int callingUid,
13944            int userId) {
13945        intent = new Intent(intent);
13946
13947        // By default broadcasts do not go to stopped apps.
13948        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13949
13950        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13951            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13952            + " ordered=" + ordered + " userid=" + userId);
13953        if ((resultTo != null) && !ordered) {
13954            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13955        }
13956
13957        userId = handleIncomingUser(callingPid, callingUid, userId,
13958                true, false, "broadcast", callerPackage);
13959
13960        // Make sure that the user who is receiving this broadcast is started.
13961        // If not, we will just skip it.
13962        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13963            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13964                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13965                Slog.w(TAG, "Skipping broadcast of " + intent
13966                        + ": user " + userId + " is stopped");
13967                return ActivityManager.BROADCAST_SUCCESS;
13968            }
13969        }
13970
13971        /*
13972         * Prevent non-system code (defined here to be non-persistent
13973         * processes) from sending protected broadcasts.
13974         */
13975        int callingAppId = UserHandle.getAppId(callingUid);
13976        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13977                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13978                || callingUid == 0) {
13979            // Always okay.
13980        } else if (callerApp == null || !callerApp.persistent) {
13981            try {
13982                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13983                        intent.getAction())) {
13984                    String msg = "Permission Denial: not allowed to send broadcast "
13985                            + intent.getAction() + " from pid="
13986                            + callingPid + ", uid=" + callingUid;
13987                    Slog.w(TAG, msg);
13988                    throw new SecurityException(msg);
13989                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13990                    // Special case for compatibility: we don't want apps to send this,
13991                    // but historically it has not been protected and apps may be using it
13992                    // to poke their own app widget.  So, instead of making it protected,
13993                    // just limit it to the caller.
13994                    if (callerApp == null) {
13995                        String msg = "Permission Denial: not allowed to send broadcast "
13996                                + intent.getAction() + " from unknown caller.";
13997                        Slog.w(TAG, msg);
13998                        throw new SecurityException(msg);
13999                    } else if (intent.getComponent() != null) {
14000                        // They are good enough to send to an explicit component...  verify
14001                        // it is being sent to the calling app.
14002                        if (!intent.getComponent().getPackageName().equals(
14003                                callerApp.info.packageName)) {
14004                            String msg = "Permission Denial: not allowed to send broadcast "
14005                                    + intent.getAction() + " to "
14006                                    + intent.getComponent().getPackageName() + " from "
14007                                    + callerApp.info.packageName;
14008                            Slog.w(TAG, msg);
14009                            throw new SecurityException(msg);
14010                        }
14011                    } else {
14012                        // Limit broadcast to their own package.
14013                        intent.setPackage(callerApp.info.packageName);
14014                    }
14015                }
14016            } catch (RemoteException e) {
14017                Slog.w(TAG, "Remote exception", e);
14018                return ActivityManager.BROADCAST_SUCCESS;
14019            }
14020        }
14021
14022        // Handle special intents: if this broadcast is from the package
14023        // manager about a package being removed, we need to remove all of
14024        // its activities from the history stack.
14025        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14026                intent.getAction());
14027        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14028                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14029                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14030                || uidRemoved) {
14031            if (checkComponentPermission(
14032                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14033                    callingPid, callingUid, -1, true)
14034                    == PackageManager.PERMISSION_GRANTED) {
14035                if (uidRemoved) {
14036                    final Bundle intentExtras = intent.getExtras();
14037                    final int uid = intentExtras != null
14038                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14039                    if (uid >= 0) {
14040                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14041                        synchronized (bs) {
14042                            bs.removeUidStatsLocked(uid);
14043                        }
14044                        mAppOpsService.uidRemoved(uid);
14045                    }
14046                } else {
14047                    // If resources are unavailable just force stop all
14048                    // those packages and flush the attribute cache as well.
14049                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14050                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14051                        if (list != null && (list.length > 0)) {
14052                            for (String pkg : list) {
14053                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14054                                        "storage unmount");
14055                            }
14056                            sendPackageBroadcastLocked(
14057                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14058                        }
14059                    } else {
14060                        Uri data = intent.getData();
14061                        String ssp;
14062                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14063                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14064                                    intent.getAction());
14065                            boolean fullUninstall = removed &&
14066                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14067                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14068                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14069                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14070                                        false, fullUninstall, userId,
14071                                        removed ? "pkg removed" : "pkg changed");
14072                            }
14073                            if (removed) {
14074                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14075                                        new String[] {ssp}, userId);
14076                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14077                                    mAppOpsService.packageRemoved(
14078                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14079
14080                                    // Remove all permissions granted from/to this package
14081                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14082                                }
14083                            }
14084                        }
14085                    }
14086                }
14087            } else {
14088                String msg = "Permission Denial: " + intent.getAction()
14089                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14090                        + ", uid=" + callingUid + ")"
14091                        + " requires "
14092                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14093                Slog.w(TAG, msg);
14094                throw new SecurityException(msg);
14095            }
14096
14097        // Special case for adding a package: by default turn on compatibility
14098        // mode.
14099        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14100            Uri data = intent.getData();
14101            String ssp;
14102            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14103                mCompatModePackages.handlePackageAddedLocked(ssp,
14104                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14105            }
14106        }
14107
14108        /*
14109         * If this is the time zone changed action, queue up a message that will reset the timezone
14110         * of all currently running processes. This message will get queued up before the broadcast
14111         * happens.
14112         */
14113        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14114            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14115        }
14116
14117        /*
14118         * If the user set the time, let all running processes know.
14119         */
14120        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14121            final int is24Hour = intent.getBooleanExtra(
14122                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14123            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14124        }
14125
14126        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14127            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14128        }
14129
14130        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14131            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14132            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14133        }
14134
14135        // Add to the sticky list if requested.
14136        if (sticky) {
14137            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14138                    callingPid, callingUid)
14139                    != PackageManager.PERMISSION_GRANTED) {
14140                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14141                        + callingPid + ", uid=" + callingUid
14142                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14143                Slog.w(TAG, msg);
14144                throw new SecurityException(msg);
14145            }
14146            if (requiredPermission != null) {
14147                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14148                        + " and enforce permission " + requiredPermission);
14149                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14150            }
14151            if (intent.getComponent() != null) {
14152                throw new SecurityException(
14153                        "Sticky broadcasts can't target a specific component");
14154            }
14155            // We use userId directly here, since the "all" target is maintained
14156            // as a separate set of sticky broadcasts.
14157            if (userId != UserHandle.USER_ALL) {
14158                // But first, if this is not a broadcast to all users, then
14159                // make sure it doesn't conflict with an existing broadcast to
14160                // all users.
14161                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14162                        UserHandle.USER_ALL);
14163                if (stickies != null) {
14164                    ArrayList<Intent> list = stickies.get(intent.getAction());
14165                    if (list != null) {
14166                        int N = list.size();
14167                        int i;
14168                        for (i=0; i<N; i++) {
14169                            if (intent.filterEquals(list.get(i))) {
14170                                throw new IllegalArgumentException(
14171                                        "Sticky broadcast " + intent + " for user "
14172                                        + userId + " conflicts with existing global broadcast");
14173                            }
14174                        }
14175                    }
14176                }
14177            }
14178            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14179            if (stickies == null) {
14180                stickies = new ArrayMap<String, ArrayList<Intent>>();
14181                mStickyBroadcasts.put(userId, stickies);
14182            }
14183            ArrayList<Intent> list = stickies.get(intent.getAction());
14184            if (list == null) {
14185                list = new ArrayList<Intent>();
14186                stickies.put(intent.getAction(), list);
14187            }
14188            int N = list.size();
14189            int i;
14190            for (i=0; i<N; i++) {
14191                if (intent.filterEquals(list.get(i))) {
14192                    // This sticky already exists, replace it.
14193                    list.set(i, new Intent(intent));
14194                    break;
14195                }
14196            }
14197            if (i >= N) {
14198                list.add(new Intent(intent));
14199            }
14200        }
14201
14202        int[] users;
14203        if (userId == UserHandle.USER_ALL) {
14204            // Caller wants broadcast to go to all started users.
14205            users = mStartedUserArray;
14206        } else {
14207            // Caller wants broadcast to go to one specific user.
14208            users = new int[] {userId};
14209        }
14210
14211        // Figure out who all will receive this broadcast.
14212        List receivers = null;
14213        List<BroadcastFilter> registeredReceivers = null;
14214        // Need to resolve the intent to interested receivers...
14215        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14216                 == 0) {
14217            receivers = collectReceiverComponents(intent, resolvedType, users);
14218        }
14219        if (intent.getComponent() == null) {
14220            registeredReceivers = mReceiverResolver.queryIntent(intent,
14221                    resolvedType, false, userId);
14222        }
14223
14224        final boolean replacePending =
14225                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14226
14227        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14228                + " replacePending=" + replacePending);
14229
14230        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14231        if (!ordered && NR > 0) {
14232            // If we are not serializing this broadcast, then send the
14233            // registered receivers separately so they don't wait for the
14234            // components to be launched.
14235            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14236            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14237                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14238                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14239                    ordered, sticky, false, userId);
14240            if (DEBUG_BROADCAST) Slog.v(
14241                    TAG, "Enqueueing parallel broadcast " + r);
14242            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14243            if (!replaced) {
14244                queue.enqueueParallelBroadcastLocked(r);
14245                queue.scheduleBroadcastsLocked();
14246            }
14247            registeredReceivers = null;
14248            NR = 0;
14249        }
14250
14251        // Merge into one list.
14252        int ir = 0;
14253        if (receivers != null) {
14254            // A special case for PACKAGE_ADDED: do not allow the package
14255            // being added to see this broadcast.  This prevents them from
14256            // using this as a back door to get run as soon as they are
14257            // installed.  Maybe in the future we want to have a special install
14258            // broadcast or such for apps, but we'd like to deliberately make
14259            // this decision.
14260            String skipPackages[] = null;
14261            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14262                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14263                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14264                Uri data = intent.getData();
14265                if (data != null) {
14266                    String pkgName = data.getSchemeSpecificPart();
14267                    if (pkgName != null) {
14268                        skipPackages = new String[] { pkgName };
14269                    }
14270                }
14271            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14272                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14273            }
14274            if (skipPackages != null && (skipPackages.length > 0)) {
14275                for (String skipPackage : skipPackages) {
14276                    if (skipPackage != null) {
14277                        int NT = receivers.size();
14278                        for (int it=0; it<NT; it++) {
14279                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14280                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14281                                receivers.remove(it);
14282                                it--;
14283                                NT--;
14284                            }
14285                        }
14286                    }
14287                }
14288            }
14289
14290            int NT = receivers != null ? receivers.size() : 0;
14291            int it = 0;
14292            ResolveInfo curt = null;
14293            BroadcastFilter curr = null;
14294            while (it < NT && ir < NR) {
14295                if (curt == null) {
14296                    curt = (ResolveInfo)receivers.get(it);
14297                }
14298                if (curr == null) {
14299                    curr = registeredReceivers.get(ir);
14300                }
14301                if (curr.getPriority() >= curt.priority) {
14302                    // Insert this broadcast record into the final list.
14303                    receivers.add(it, curr);
14304                    ir++;
14305                    curr = null;
14306                    it++;
14307                    NT++;
14308                } else {
14309                    // Skip to the next ResolveInfo in the final list.
14310                    it++;
14311                    curt = null;
14312                }
14313            }
14314        }
14315        while (ir < NR) {
14316            if (receivers == null) {
14317                receivers = new ArrayList();
14318            }
14319            receivers.add(registeredReceivers.get(ir));
14320            ir++;
14321        }
14322
14323        if ((receivers != null && receivers.size() > 0)
14324                || resultTo != null) {
14325            BroadcastQueue queue = broadcastQueueForIntent(intent);
14326            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14327                    callerPackage, callingPid, callingUid, resolvedType,
14328                    requiredPermission, appOp, receivers, resultTo, resultCode,
14329                    resultData, map, ordered, sticky, false, userId);
14330            if (DEBUG_BROADCAST) Slog.v(
14331                    TAG, "Enqueueing ordered broadcast " + r
14332                    + ": prev had " + queue.mOrderedBroadcasts.size());
14333            if (DEBUG_BROADCAST) {
14334                int seq = r.intent.getIntExtra("seq", -1);
14335                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14336            }
14337            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14338            if (!replaced) {
14339                queue.enqueueOrderedBroadcastLocked(r);
14340                queue.scheduleBroadcastsLocked();
14341            }
14342        }
14343
14344        return ActivityManager.BROADCAST_SUCCESS;
14345    }
14346
14347    final Intent verifyBroadcastLocked(Intent intent) {
14348        // Refuse possible leaked file descriptors
14349        if (intent != null && intent.hasFileDescriptors() == true) {
14350            throw new IllegalArgumentException("File descriptors passed in Intent");
14351        }
14352
14353        int flags = intent.getFlags();
14354
14355        if (!mProcessesReady) {
14356            // if the caller really truly claims to know what they're doing, go
14357            // ahead and allow the broadcast without launching any receivers
14358            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14359                intent = new Intent(intent);
14360                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14361            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14362                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14363                        + " before boot completion");
14364                throw new IllegalStateException("Cannot broadcast before boot completed");
14365            }
14366        }
14367
14368        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14369            throw new IllegalArgumentException(
14370                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14371        }
14372
14373        return intent;
14374    }
14375
14376    public final int broadcastIntent(IApplicationThread caller,
14377            Intent intent, String resolvedType, IIntentReceiver resultTo,
14378            int resultCode, String resultData, Bundle map,
14379            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14380        enforceNotIsolatedCaller("broadcastIntent");
14381        synchronized(this) {
14382            intent = verifyBroadcastLocked(intent);
14383
14384            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14385            final int callingPid = Binder.getCallingPid();
14386            final int callingUid = Binder.getCallingUid();
14387            final long origId = Binder.clearCallingIdentity();
14388            int res = broadcastIntentLocked(callerApp,
14389                    callerApp != null ? callerApp.info.packageName : null,
14390                    intent, resolvedType, resultTo,
14391                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14392                    callingPid, callingUid, userId);
14393            Binder.restoreCallingIdentity(origId);
14394            return res;
14395        }
14396    }
14397
14398    int broadcastIntentInPackage(String packageName, int uid,
14399            Intent intent, String resolvedType, IIntentReceiver resultTo,
14400            int resultCode, String resultData, Bundle map,
14401            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14402        synchronized(this) {
14403            intent = verifyBroadcastLocked(intent);
14404
14405            final long origId = Binder.clearCallingIdentity();
14406            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14407                    resultTo, resultCode, resultData, map, requiredPermission,
14408                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14409            Binder.restoreCallingIdentity(origId);
14410            return res;
14411        }
14412    }
14413
14414    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14415        // Refuse possible leaked file descriptors
14416        if (intent != null && intent.hasFileDescriptors() == true) {
14417            throw new IllegalArgumentException("File descriptors passed in Intent");
14418        }
14419
14420        userId = handleIncomingUser(Binder.getCallingPid(),
14421                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14422
14423        synchronized(this) {
14424            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14425                    != PackageManager.PERMISSION_GRANTED) {
14426                String msg = "Permission Denial: unbroadcastIntent() from pid="
14427                        + Binder.getCallingPid()
14428                        + ", uid=" + Binder.getCallingUid()
14429                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14430                Slog.w(TAG, msg);
14431                throw new SecurityException(msg);
14432            }
14433            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14434            if (stickies != null) {
14435                ArrayList<Intent> list = stickies.get(intent.getAction());
14436                if (list != null) {
14437                    int N = list.size();
14438                    int i;
14439                    for (i=0; i<N; i++) {
14440                        if (intent.filterEquals(list.get(i))) {
14441                            list.remove(i);
14442                            break;
14443                        }
14444                    }
14445                    if (list.size() <= 0) {
14446                        stickies.remove(intent.getAction());
14447                    }
14448                }
14449                if (stickies.size() <= 0) {
14450                    mStickyBroadcasts.remove(userId);
14451                }
14452            }
14453        }
14454    }
14455
14456    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14457            String resultData, Bundle resultExtras, boolean resultAbort) {
14458        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14459        if (r == null) {
14460            Slog.w(TAG, "finishReceiver called but not found on queue");
14461            return false;
14462        }
14463
14464        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14465    }
14466
14467    void backgroundServicesFinishedLocked(int userId) {
14468        for (BroadcastQueue queue : mBroadcastQueues) {
14469            queue.backgroundServicesFinishedLocked(userId);
14470        }
14471    }
14472
14473    public void finishReceiver(IBinder who, int resultCode, String resultData,
14474            Bundle resultExtras, boolean resultAbort) {
14475        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14476
14477        // Refuse possible leaked file descriptors
14478        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14479            throw new IllegalArgumentException("File descriptors passed in Bundle");
14480        }
14481
14482        final long origId = Binder.clearCallingIdentity();
14483        try {
14484            boolean doNext = false;
14485            BroadcastRecord r;
14486
14487            synchronized(this) {
14488                r = broadcastRecordForReceiverLocked(who);
14489                if (r != null) {
14490                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14491                        resultData, resultExtras, resultAbort, true);
14492                }
14493            }
14494
14495            if (doNext) {
14496                r.queue.processNextBroadcast(false);
14497            }
14498            trimApplications();
14499        } finally {
14500            Binder.restoreCallingIdentity(origId);
14501        }
14502    }
14503
14504    // =========================================================
14505    // INSTRUMENTATION
14506    // =========================================================
14507
14508    public boolean startInstrumentation(ComponentName className,
14509            String profileFile, int flags, Bundle arguments,
14510            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14511            int userId, String abiOverride) {
14512        enforceNotIsolatedCaller("startInstrumentation");
14513        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14514                userId, false, true, "startInstrumentation", null);
14515        // Refuse possible leaked file descriptors
14516        if (arguments != null && arguments.hasFileDescriptors()) {
14517            throw new IllegalArgumentException("File descriptors passed in Bundle");
14518        }
14519
14520        synchronized(this) {
14521            InstrumentationInfo ii = null;
14522            ApplicationInfo ai = null;
14523            try {
14524                ii = mContext.getPackageManager().getInstrumentationInfo(
14525                    className, STOCK_PM_FLAGS);
14526                ai = AppGlobals.getPackageManager().getApplicationInfo(
14527                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14528            } catch (PackageManager.NameNotFoundException e) {
14529            } catch (RemoteException e) {
14530            }
14531            if (ii == null) {
14532                reportStartInstrumentationFailure(watcher, className,
14533                        "Unable to find instrumentation info for: " + className);
14534                return false;
14535            }
14536            if (ai == null) {
14537                reportStartInstrumentationFailure(watcher, className,
14538                        "Unable to find instrumentation target package: " + ii.targetPackage);
14539                return false;
14540            }
14541
14542            int match = mContext.getPackageManager().checkSignatures(
14543                    ii.targetPackage, ii.packageName);
14544            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14545                String msg = "Permission Denial: starting instrumentation "
14546                        + className + " from pid="
14547                        + Binder.getCallingPid()
14548                        + ", uid=" + Binder.getCallingPid()
14549                        + " not allowed because package " + ii.packageName
14550                        + " does not have a signature matching the target "
14551                        + ii.targetPackage;
14552                reportStartInstrumentationFailure(watcher, className, msg);
14553                throw new SecurityException(msg);
14554            }
14555
14556            final long origId = Binder.clearCallingIdentity();
14557            // Instrumentation can kill and relaunch even persistent processes
14558            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14559                    "start instr");
14560            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14561            app.instrumentationClass = className;
14562            app.instrumentationInfo = ai;
14563            app.instrumentationProfileFile = profileFile;
14564            app.instrumentationArguments = arguments;
14565            app.instrumentationWatcher = watcher;
14566            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14567            app.instrumentationResultClass = className;
14568            Binder.restoreCallingIdentity(origId);
14569        }
14570
14571        return true;
14572    }
14573
14574    /**
14575     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14576     * error to the logs, but if somebody is watching, send the report there too.  This enables
14577     * the "am" command to report errors with more information.
14578     *
14579     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14580     * @param cn The component name of the instrumentation.
14581     * @param report The error report.
14582     */
14583    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14584            ComponentName cn, String report) {
14585        Slog.w(TAG, report);
14586        try {
14587            if (watcher != null) {
14588                Bundle results = new Bundle();
14589                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14590                results.putString("Error", report);
14591                watcher.instrumentationStatus(cn, -1, results);
14592            }
14593        } catch (RemoteException e) {
14594            Slog.w(TAG, e);
14595        }
14596    }
14597
14598    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14599        if (app.instrumentationWatcher != null) {
14600            try {
14601                // NOTE:  IInstrumentationWatcher *must* be oneway here
14602                app.instrumentationWatcher.instrumentationFinished(
14603                    app.instrumentationClass,
14604                    resultCode,
14605                    results);
14606            } catch (RemoteException e) {
14607            }
14608        }
14609        if (app.instrumentationUiAutomationConnection != null) {
14610            try {
14611                app.instrumentationUiAutomationConnection.shutdown();
14612            } catch (RemoteException re) {
14613                /* ignore */
14614            }
14615            // Only a UiAutomation can set this flag and now that
14616            // it is finished we make sure it is reset to its default.
14617            mUserIsMonkey = false;
14618        }
14619        app.instrumentationWatcher = null;
14620        app.instrumentationUiAutomationConnection = null;
14621        app.instrumentationClass = null;
14622        app.instrumentationInfo = null;
14623        app.instrumentationProfileFile = null;
14624        app.instrumentationArguments = null;
14625
14626        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14627                "finished inst");
14628    }
14629
14630    public void finishInstrumentation(IApplicationThread target,
14631            int resultCode, Bundle results) {
14632        int userId = UserHandle.getCallingUserId();
14633        // Refuse possible leaked file descriptors
14634        if (results != null && results.hasFileDescriptors()) {
14635            throw new IllegalArgumentException("File descriptors passed in Intent");
14636        }
14637
14638        synchronized(this) {
14639            ProcessRecord app = getRecordForAppLocked(target);
14640            if (app == null) {
14641                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14642                return;
14643            }
14644            final long origId = Binder.clearCallingIdentity();
14645            finishInstrumentationLocked(app, resultCode, results);
14646            Binder.restoreCallingIdentity(origId);
14647        }
14648    }
14649
14650    // =========================================================
14651    // CONFIGURATION
14652    // =========================================================
14653
14654    public ConfigurationInfo getDeviceConfigurationInfo() {
14655        ConfigurationInfo config = new ConfigurationInfo();
14656        synchronized (this) {
14657            config.reqTouchScreen = mConfiguration.touchscreen;
14658            config.reqKeyboardType = mConfiguration.keyboard;
14659            config.reqNavigation = mConfiguration.navigation;
14660            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14661                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14662                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14663            }
14664            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14665                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14666                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14667            }
14668            config.reqGlEsVersion = GL_ES_VERSION;
14669        }
14670        return config;
14671    }
14672
14673    ActivityStack getFocusedStack() {
14674        return mStackSupervisor.getFocusedStack();
14675    }
14676
14677    public Configuration getConfiguration() {
14678        Configuration ci;
14679        synchronized(this) {
14680            ci = new Configuration(mConfiguration);
14681        }
14682        return ci;
14683    }
14684
14685    public void updatePersistentConfiguration(Configuration values) {
14686        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14687                "updateConfiguration()");
14688        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14689                "updateConfiguration()");
14690        if (values == null) {
14691            throw new NullPointerException("Configuration must not be null");
14692        }
14693
14694        synchronized(this) {
14695            final long origId = Binder.clearCallingIdentity();
14696            updateConfigurationLocked(values, null, true, false);
14697            Binder.restoreCallingIdentity(origId);
14698        }
14699    }
14700
14701    public void updateConfiguration(Configuration values) {
14702        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14703                "updateConfiguration()");
14704
14705        synchronized(this) {
14706            if (values == null && mWindowManager != null) {
14707                // sentinel: fetch the current configuration from the window manager
14708                values = mWindowManager.computeNewConfiguration();
14709            }
14710
14711            if (mWindowManager != null) {
14712                mProcessList.applyDisplaySize(mWindowManager);
14713            }
14714
14715            final long origId = Binder.clearCallingIdentity();
14716            if (values != null) {
14717                Settings.System.clearConfiguration(values);
14718            }
14719            updateConfigurationLocked(values, null, false, false);
14720            Binder.restoreCallingIdentity(origId);
14721        }
14722    }
14723
14724    /**
14725     * Do either or both things: (1) change the current configuration, and (2)
14726     * make sure the given activity is running with the (now) current
14727     * configuration.  Returns true if the activity has been left running, or
14728     * false if <var>starting</var> is being destroyed to match the new
14729     * configuration.
14730     * @param persistent TODO
14731     */
14732    boolean updateConfigurationLocked(Configuration values,
14733            ActivityRecord starting, boolean persistent, boolean initLocale) {
14734        int changes = 0;
14735
14736        if (values != null) {
14737            Configuration newConfig = new Configuration(mConfiguration);
14738            changes = newConfig.updateFrom(values);
14739            if (changes != 0) {
14740                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14741                    Slog.i(TAG, "Updating configuration to: " + values);
14742                }
14743
14744                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14745
14746                if (values.locale != null && !initLocale) {
14747                    saveLocaleLocked(values.locale,
14748                                     !values.locale.equals(mConfiguration.locale),
14749                                     values.userSetLocale);
14750                }
14751
14752                mConfigurationSeq++;
14753                if (mConfigurationSeq <= 0) {
14754                    mConfigurationSeq = 1;
14755                }
14756                newConfig.seq = mConfigurationSeq;
14757                mConfiguration = newConfig;
14758                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14759                mUsageStatsService.noteStartConfig(newConfig);
14760
14761                final Configuration configCopy = new Configuration(mConfiguration);
14762
14763                // TODO: If our config changes, should we auto dismiss any currently
14764                // showing dialogs?
14765                mShowDialogs = shouldShowDialogs(newConfig);
14766
14767                AttributeCache ac = AttributeCache.instance();
14768                if (ac != null) {
14769                    ac.updateConfiguration(configCopy);
14770                }
14771
14772                // Make sure all resources in our process are updated
14773                // right now, so that anyone who is going to retrieve
14774                // resource values after we return will be sure to get
14775                // the new ones.  This is especially important during
14776                // boot, where the first config change needs to guarantee
14777                // all resources have that config before following boot
14778                // code is executed.
14779                mSystemThread.applyConfigurationToResources(configCopy);
14780
14781                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14782                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14783                    msg.obj = new Configuration(configCopy);
14784                    mHandler.sendMessage(msg);
14785                }
14786
14787                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14788                    ProcessRecord app = mLruProcesses.get(i);
14789                    try {
14790                        if (app.thread != null) {
14791                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14792                                    + app.processName + " new config " + mConfiguration);
14793                            app.thread.scheduleConfigurationChanged(configCopy);
14794                        }
14795                    } catch (Exception e) {
14796                    }
14797                }
14798                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14799                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14800                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14801                        | Intent.FLAG_RECEIVER_FOREGROUND);
14802                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14803                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14804                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14805                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14806                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14807                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14808                    broadcastIntentLocked(null, null, intent,
14809                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14810                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14811                }
14812            }
14813        }
14814
14815        boolean kept = true;
14816        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14817        // mainStack is null during startup.
14818        if (mainStack != null) {
14819            if (changes != 0 && starting == null) {
14820                // If the configuration changed, and the caller is not already
14821                // in the process of starting an activity, then find the top
14822                // activity to check if its configuration needs to change.
14823                starting = mainStack.topRunningActivityLocked(null);
14824            }
14825
14826            if (starting != null) {
14827                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14828                // And we need to make sure at this point that all other activities
14829                // are made visible with the correct configuration.
14830                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14831            }
14832        }
14833
14834        if (values != null && mWindowManager != null) {
14835            mWindowManager.setNewConfiguration(mConfiguration);
14836        }
14837
14838        return kept;
14839    }
14840
14841    /**
14842     * Decide based on the configuration whether we should shouw the ANR,
14843     * crash, etc dialogs.  The idea is that if there is no affordnace to
14844     * press the on-screen buttons, we shouldn't show the dialog.
14845     *
14846     * A thought: SystemUI might also want to get told about this, the Power
14847     * dialog / global actions also might want different behaviors.
14848     */
14849    private static final boolean shouldShowDialogs(Configuration config) {
14850        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14851                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14852    }
14853
14854    /**
14855     * Save the locale.  You must be inside a synchronized (this) block.
14856     */
14857    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14858        if(isDiff) {
14859            SystemProperties.set("user.language", l.getLanguage());
14860            SystemProperties.set("user.region", l.getCountry());
14861        }
14862
14863        if(isPersist) {
14864            SystemProperties.set("persist.sys.language", l.getLanguage());
14865            SystemProperties.set("persist.sys.country", l.getCountry());
14866            SystemProperties.set("persist.sys.localevar", l.getVariant());
14867        }
14868    }
14869
14870    @Override
14871    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14872        ActivityRecord srec = ActivityRecord.forToken(token);
14873        return srec != null && srec.task.affinity != null &&
14874                srec.task.affinity.equals(destAffinity);
14875    }
14876
14877    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14878            Intent resultData) {
14879
14880        synchronized (this) {
14881            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14882            if (stack != null) {
14883                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14884            }
14885            return false;
14886        }
14887    }
14888
14889    public int getLaunchedFromUid(IBinder activityToken) {
14890        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14891        if (srec == null) {
14892            return -1;
14893        }
14894        return srec.launchedFromUid;
14895    }
14896
14897    public String getLaunchedFromPackage(IBinder activityToken) {
14898        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14899        if (srec == null) {
14900            return null;
14901        }
14902        return srec.launchedFromPackage;
14903    }
14904
14905    // =========================================================
14906    // LIFETIME MANAGEMENT
14907    // =========================================================
14908
14909    // Returns which broadcast queue the app is the current [or imminent] receiver
14910    // on, or 'null' if the app is not an active broadcast recipient.
14911    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14912        BroadcastRecord r = app.curReceiver;
14913        if (r != null) {
14914            return r.queue;
14915        }
14916
14917        // It's not the current receiver, but it might be starting up to become one
14918        synchronized (this) {
14919            for (BroadcastQueue queue : mBroadcastQueues) {
14920                r = queue.mPendingBroadcast;
14921                if (r != null && r.curApp == app) {
14922                    // found it; report which queue it's in
14923                    return queue;
14924                }
14925            }
14926        }
14927
14928        return null;
14929    }
14930
14931    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14932            boolean doingAll, long now) {
14933        if (mAdjSeq == app.adjSeq) {
14934            // This adjustment has already been computed.
14935            return app.curRawAdj;
14936        }
14937
14938        if (app.thread == null) {
14939            app.adjSeq = mAdjSeq;
14940            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14941            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14942            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14943        }
14944
14945        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14946        app.adjSource = null;
14947        app.adjTarget = null;
14948        app.empty = false;
14949        app.cached = false;
14950
14951        final int activitiesSize = app.activities.size();
14952
14953        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14954            // The max adjustment doesn't allow this app to be anything
14955            // below foreground, so it is not worth doing work for it.
14956            app.adjType = "fixed";
14957            app.adjSeq = mAdjSeq;
14958            app.curRawAdj = app.maxAdj;
14959            app.foregroundActivities = false;
14960            app.keeping = true;
14961            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14962            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14963            // System processes can do UI, and when they do we want to have
14964            // them trim their memory after the user leaves the UI.  To
14965            // facilitate this, here we need to determine whether or not it
14966            // is currently showing UI.
14967            app.systemNoUi = true;
14968            if (app == TOP_APP) {
14969                app.systemNoUi = false;
14970            } else if (activitiesSize > 0) {
14971                for (int j = 0; j < activitiesSize; j++) {
14972                    final ActivityRecord r = app.activities.get(j);
14973                    if (r.visible) {
14974                        app.systemNoUi = false;
14975                    }
14976                }
14977            }
14978            if (!app.systemNoUi) {
14979                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14980            }
14981            return (app.curAdj=app.maxAdj);
14982        }
14983
14984        app.keeping = false;
14985        app.systemNoUi = false;
14986
14987        // Determine the importance of the process, starting with most
14988        // important to least, and assign an appropriate OOM adjustment.
14989        int adj;
14990        int schedGroup;
14991        int procState;
14992        boolean foregroundActivities = false;
14993        boolean interesting = false;
14994        BroadcastQueue queue;
14995        if (app == TOP_APP) {
14996            // The last app on the list is the foreground app.
14997            adj = ProcessList.FOREGROUND_APP_ADJ;
14998            schedGroup = Process.THREAD_GROUP_DEFAULT;
14999            app.adjType = "top-activity";
15000            foregroundActivities = true;
15001            interesting = true;
15002            procState = ActivityManager.PROCESS_STATE_TOP;
15003        } else if (app.instrumentationClass != null) {
15004            // Don't want to kill running instrumentation.
15005            adj = ProcessList.FOREGROUND_APP_ADJ;
15006            schedGroup = Process.THREAD_GROUP_DEFAULT;
15007            app.adjType = "instrumentation";
15008            interesting = true;
15009            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15010        } else if ((queue = isReceivingBroadcast(app)) != null) {
15011            // An app that is currently receiving a broadcast also
15012            // counts as being in the foreground for OOM killer purposes.
15013            // It's placed in a sched group based on the nature of the
15014            // broadcast as reflected by which queue it's active in.
15015            adj = ProcessList.FOREGROUND_APP_ADJ;
15016            schedGroup = (queue == mFgBroadcastQueue)
15017                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15018            app.adjType = "broadcast";
15019            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15020        } else if (app.executingServices.size() > 0) {
15021            // An app that is currently executing a service callback also
15022            // counts as being in the foreground.
15023            adj = ProcessList.FOREGROUND_APP_ADJ;
15024            schedGroup = app.execServicesFg ?
15025                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15026            app.adjType = "exec-service";
15027            procState = ActivityManager.PROCESS_STATE_SERVICE;
15028            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15029        } else {
15030            // As far as we know the process is empty.  We may change our mind later.
15031            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15032            // At this point we don't actually know the adjustment.  Use the cached adj
15033            // value that the caller wants us to.
15034            adj = cachedAdj;
15035            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15036            app.cached = true;
15037            app.empty = true;
15038            app.adjType = "cch-empty";
15039        }
15040
15041        // Examine all activities if not already foreground.
15042        if (!foregroundActivities && activitiesSize > 0) {
15043            for (int j = 0; j < activitiesSize; j++) {
15044                final ActivityRecord r = app.activities.get(j);
15045                if (r.app != app) {
15046                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15047                            + app + "?!?");
15048                    continue;
15049                }
15050                if (r.visible) {
15051                    // App has a visible activity; only upgrade adjustment.
15052                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15053                        adj = ProcessList.VISIBLE_APP_ADJ;
15054                        app.adjType = "visible";
15055                    }
15056                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15057                        procState = ActivityManager.PROCESS_STATE_TOP;
15058                    }
15059                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15060                    app.cached = false;
15061                    app.empty = false;
15062                    foregroundActivities = true;
15063                    break;
15064                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15065                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15066                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15067                        app.adjType = "pausing";
15068                    }
15069                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15070                        procState = ActivityManager.PROCESS_STATE_TOP;
15071                    }
15072                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15073                    app.cached = false;
15074                    app.empty = false;
15075                    foregroundActivities = true;
15076                } else if (r.state == ActivityState.STOPPING) {
15077                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15078                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15079                        app.adjType = "stopping";
15080                    }
15081                    // For the process state, we will at this point consider the
15082                    // process to be cached.  It will be cached either as an activity
15083                    // or empty depending on whether the activity is finishing.  We do
15084                    // this so that we can treat the process as cached for purposes of
15085                    // memory trimming (determing current memory level, trim command to
15086                    // send to process) since there can be an arbitrary number of stopping
15087                    // processes and they should soon all go into the cached state.
15088                    if (!r.finishing) {
15089                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15090                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15091                        }
15092                    }
15093                    app.cached = false;
15094                    app.empty = false;
15095                    foregroundActivities = true;
15096                } else {
15097                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15098                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15099                        app.adjType = "cch-act";
15100                    }
15101                }
15102            }
15103        }
15104
15105        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15106            if (app.foregroundServices) {
15107                // The user is aware of this app, so make it visible.
15108                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15109                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15110                app.cached = false;
15111                app.adjType = "fg-service";
15112                schedGroup = Process.THREAD_GROUP_DEFAULT;
15113            } else if (app.forcingToForeground != null) {
15114                // The user is aware of this app, so make it visible.
15115                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15116                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15117                app.cached = false;
15118                app.adjType = "force-fg";
15119                app.adjSource = app.forcingToForeground;
15120                schedGroup = Process.THREAD_GROUP_DEFAULT;
15121            }
15122        }
15123
15124        if (app.foregroundServices) {
15125            interesting = true;
15126        }
15127
15128        if (app == mHeavyWeightProcess) {
15129            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15130                // We don't want to kill the current heavy-weight process.
15131                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15132                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15133                app.cached = false;
15134                app.adjType = "heavy";
15135            }
15136            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15137                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15138            }
15139        }
15140
15141        if (app == mHomeProcess) {
15142            if (adj > ProcessList.HOME_APP_ADJ) {
15143                // This process is hosting what we currently consider to be the
15144                // home app, so we don't want to let it go into the background.
15145                adj = ProcessList.HOME_APP_ADJ;
15146                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15147                app.cached = false;
15148                app.adjType = "home";
15149            }
15150            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15151                procState = ActivityManager.PROCESS_STATE_HOME;
15152            }
15153        }
15154
15155        if (app == mPreviousProcess && app.activities.size() > 0) {
15156            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15157                // This was the previous process that showed UI to the user.
15158                // We want to try to keep it around more aggressively, to give
15159                // a good experience around switching between two apps.
15160                adj = ProcessList.PREVIOUS_APP_ADJ;
15161                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15162                app.cached = false;
15163                app.adjType = "previous";
15164            }
15165            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15166                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15167            }
15168        }
15169
15170        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15171                + " reason=" + app.adjType);
15172
15173        // By default, we use the computed adjustment.  It may be changed if
15174        // there are applications dependent on our services or providers, but
15175        // this gives us a baseline and makes sure we don't get into an
15176        // infinite recursion.
15177        app.adjSeq = mAdjSeq;
15178        app.curRawAdj = adj;
15179        app.hasStartedServices = false;
15180
15181        if (mBackupTarget != null && app == mBackupTarget.app) {
15182            // If possible we want to avoid killing apps while they're being backed up
15183            if (adj > ProcessList.BACKUP_APP_ADJ) {
15184                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15185                adj = ProcessList.BACKUP_APP_ADJ;
15186                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15187                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15188                }
15189                app.adjType = "backup";
15190                app.cached = false;
15191            }
15192            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15193                procState = ActivityManager.PROCESS_STATE_BACKUP;
15194            }
15195        }
15196
15197        boolean mayBeTop = false;
15198
15199        for (int is = app.services.size()-1;
15200                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15201                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15202                        || procState > ActivityManager.PROCESS_STATE_TOP);
15203                is--) {
15204            ServiceRecord s = app.services.valueAt(is);
15205            if (s.startRequested) {
15206                app.hasStartedServices = true;
15207                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15208                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15209                }
15210                if (app.hasShownUi && app != mHomeProcess) {
15211                    // If this process has shown some UI, let it immediately
15212                    // go to the LRU list because it may be pretty heavy with
15213                    // UI stuff.  We'll tag it with a label just to help
15214                    // debug and understand what is going on.
15215                    if (adj > ProcessList.SERVICE_ADJ) {
15216                        app.adjType = "cch-started-ui-services";
15217                    }
15218                } else {
15219                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15220                        // This service has seen some activity within
15221                        // recent memory, so we will keep its process ahead
15222                        // of the background processes.
15223                        if (adj > ProcessList.SERVICE_ADJ) {
15224                            adj = ProcessList.SERVICE_ADJ;
15225                            app.adjType = "started-services";
15226                            app.cached = false;
15227                        }
15228                    }
15229                    // If we have let the service slide into the background
15230                    // state, still have some text describing what it is doing
15231                    // even though the service no longer has an impact.
15232                    if (adj > ProcessList.SERVICE_ADJ) {
15233                        app.adjType = "cch-started-services";
15234                    }
15235                }
15236                // Don't kill this process because it is doing work; it
15237                // has said it is doing work.
15238                app.keeping = true;
15239            }
15240            for (int conni = s.connections.size()-1;
15241                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15242                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15243                            || procState > ActivityManager.PROCESS_STATE_TOP);
15244                    conni--) {
15245                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15246                for (int i = 0;
15247                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15248                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15249                                || procState > ActivityManager.PROCESS_STATE_TOP);
15250                        i++) {
15251                    // XXX should compute this based on the max of
15252                    // all connected clients.
15253                    ConnectionRecord cr = clist.get(i);
15254                    if (cr.binding.client == app) {
15255                        // Binding to ourself is not interesting.
15256                        continue;
15257                    }
15258                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15259                        ProcessRecord client = cr.binding.client;
15260                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15261                                TOP_APP, doingAll, now);
15262                        int clientProcState = client.curProcState;
15263                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15264                            // If the other app is cached for any reason, for purposes here
15265                            // we are going to consider it empty.  The specific cached state
15266                            // doesn't propagate except under certain conditions.
15267                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15268                        }
15269                        String adjType = null;
15270                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15271                            // Not doing bind OOM management, so treat
15272                            // this guy more like a started service.
15273                            if (app.hasShownUi && app != mHomeProcess) {
15274                                // If this process has shown some UI, let it immediately
15275                                // go to the LRU list because it may be pretty heavy with
15276                                // UI stuff.  We'll tag it with a label just to help
15277                                // debug and understand what is going on.
15278                                if (adj > clientAdj) {
15279                                    adjType = "cch-bound-ui-services";
15280                                }
15281                                app.cached = false;
15282                                clientAdj = adj;
15283                                clientProcState = procState;
15284                            } else {
15285                                if (now >= (s.lastActivity
15286                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15287                                    // This service has not seen activity within
15288                                    // recent memory, so allow it to drop to the
15289                                    // LRU list if there is no other reason to keep
15290                                    // it around.  We'll also tag it with a label just
15291                                    // to help debug and undertand what is going on.
15292                                    if (adj > clientAdj) {
15293                                        adjType = "cch-bound-services";
15294                                    }
15295                                    clientAdj = adj;
15296                                }
15297                            }
15298                        }
15299                        if (adj > clientAdj) {
15300                            // If this process has recently shown UI, and
15301                            // the process that is binding to it is less
15302                            // important than being visible, then we don't
15303                            // care about the binding as much as we care
15304                            // about letting this process get into the LRU
15305                            // list to be killed and restarted if needed for
15306                            // memory.
15307                            if (app.hasShownUi && app != mHomeProcess
15308                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15309                                adjType = "cch-bound-ui-services";
15310                            } else {
15311                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15312                                        |Context.BIND_IMPORTANT)) != 0) {
15313                                    adj = clientAdj;
15314                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15315                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15316                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15317                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15318                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15319                                    adj = clientAdj;
15320                                } else {
15321                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15322                                        adj = ProcessList.VISIBLE_APP_ADJ;
15323                                    }
15324                                }
15325                                if (!client.cached) {
15326                                    app.cached = false;
15327                                }
15328                                if (client.keeping) {
15329                                    app.keeping = true;
15330                                }
15331                                adjType = "service";
15332                            }
15333                        }
15334                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15335                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15336                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15337                            }
15338                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15339                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15340                                    // Special handling of clients who are in the top state.
15341                                    // We *may* want to consider this process to be in the
15342                                    // top state as well, but only if there is not another
15343                                    // reason for it to be running.  Being on the top is a
15344                                    // special state, meaning you are specifically running
15345                                    // for the current top app.  If the process is already
15346                                    // running in the background for some other reason, it
15347                                    // is more important to continue considering it to be
15348                                    // in the background state.
15349                                    mayBeTop = true;
15350                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15351                                } else {
15352                                    // Special handling for above-top states (persistent
15353                                    // processes).  These should not bring the current process
15354                                    // into the top state, since they are not on top.  Instead
15355                                    // give them the best state after that.
15356                                    clientProcState =
15357                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15358                                }
15359                            }
15360                        } else {
15361                            if (clientProcState <
15362                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15363                                clientProcState =
15364                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15365                            }
15366                        }
15367                        if (procState > clientProcState) {
15368                            procState = clientProcState;
15369                        }
15370                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15371                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15372                            app.pendingUiClean = true;
15373                        }
15374                        if (adjType != null) {
15375                            app.adjType = adjType;
15376                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15377                                    .REASON_SERVICE_IN_USE;
15378                            app.adjSource = cr.binding.client;
15379                            app.adjSourceOom = clientAdj;
15380                            app.adjTarget = s.name;
15381                        }
15382                    }
15383                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15384                        app.treatLikeActivity = true;
15385                    }
15386                    final ActivityRecord a = cr.activity;
15387                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15388                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15389                                (a.visible || a.state == ActivityState.RESUMED
15390                                 || a.state == ActivityState.PAUSING)) {
15391                            adj = ProcessList.FOREGROUND_APP_ADJ;
15392                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15393                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15394                            }
15395                            app.cached = false;
15396                            app.adjType = "service";
15397                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15398                                    .REASON_SERVICE_IN_USE;
15399                            app.adjSource = a;
15400                            app.adjSourceOom = adj;
15401                            app.adjTarget = s.name;
15402                        }
15403                    }
15404                }
15405            }
15406        }
15407
15408        for (int provi = app.pubProviders.size()-1;
15409                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15410                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15411                        || procState > ActivityManager.PROCESS_STATE_TOP);
15412                provi--) {
15413            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15414            for (int i = cpr.connections.size()-1;
15415                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15416                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15417                            || procState > ActivityManager.PROCESS_STATE_TOP);
15418                    i--) {
15419                ContentProviderConnection conn = cpr.connections.get(i);
15420                ProcessRecord client = conn.client;
15421                if (client == app) {
15422                    // Being our own client is not interesting.
15423                    continue;
15424                }
15425                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15426                int clientProcState = client.curProcState;
15427                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15428                    // If the other app is cached for any reason, for purposes here
15429                    // we are going to consider it empty.
15430                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15431                }
15432                if (adj > clientAdj) {
15433                    if (app.hasShownUi && app != mHomeProcess
15434                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15435                        app.adjType = "cch-ui-provider";
15436                    } else {
15437                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15438                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15439                        app.adjType = "provider";
15440                    }
15441                    app.cached &= client.cached;
15442                    app.keeping |= client.keeping;
15443                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15444                            .REASON_PROVIDER_IN_USE;
15445                    app.adjSource = client;
15446                    app.adjSourceOom = clientAdj;
15447                    app.adjTarget = cpr.name;
15448                }
15449                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15450                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15451                        // Special handling of clients who are in the top state.
15452                        // We *may* want to consider this process to be in the
15453                        // top state as well, but only if there is not another
15454                        // reason for it to be running.  Being on the top is a
15455                        // special state, meaning you are specifically running
15456                        // for the current top app.  If the process is already
15457                        // running in the background for some other reason, it
15458                        // is more important to continue considering it to be
15459                        // in the background state.
15460                        mayBeTop = true;
15461                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15462                    } else {
15463                        // Special handling for above-top states (persistent
15464                        // processes).  These should not bring the current process
15465                        // into the top state, since they are not on top.  Instead
15466                        // give them the best state after that.
15467                        clientProcState =
15468                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15469                    }
15470                }
15471                if (procState > clientProcState) {
15472                    procState = clientProcState;
15473                }
15474                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15475                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15476                }
15477            }
15478            // If the provider has external (non-framework) process
15479            // dependencies, ensure that its adjustment is at least
15480            // FOREGROUND_APP_ADJ.
15481            if (cpr.hasExternalProcessHandles()) {
15482                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15483                    adj = ProcessList.FOREGROUND_APP_ADJ;
15484                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15485                    app.cached = false;
15486                    app.keeping = true;
15487                    app.adjType = "provider";
15488                    app.adjTarget = cpr.name;
15489                }
15490                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15491                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15492                }
15493            }
15494        }
15495
15496        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15497            // A client of one of our services or providers is in the top state.  We
15498            // *may* want to be in the top state, but not if we are already running in
15499            // the background for some other reason.  For the decision here, we are going
15500            // to pick out a few specific states that we want to remain in when a client
15501            // is top (states that tend to be longer-term) and otherwise allow it to go
15502            // to the top state.
15503            switch (procState) {
15504                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15505                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15506                case ActivityManager.PROCESS_STATE_SERVICE:
15507                    // These all are longer-term states, so pull them up to the top
15508                    // of the background states, but not all the way to the top state.
15509                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15510                    break;
15511                default:
15512                    // Otherwise, top is a better choice, so take it.
15513                    procState = ActivityManager.PROCESS_STATE_TOP;
15514                    break;
15515            }
15516        }
15517
15518        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15519            if (app.hasClientActivities) {
15520                // This is a cached process, but with client activities.  Mark it so.
15521                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15522                app.adjType = "cch-client-act";
15523            } else if (app.treatLikeActivity) {
15524                // This is a cached process, but somebody wants us to treat it like it has
15525                // an activity, okay!
15526                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15527                app.adjType = "cch-as-act";
15528            }
15529        }
15530
15531        if (adj == ProcessList.SERVICE_ADJ) {
15532            if (doingAll) {
15533                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15534                mNewNumServiceProcs++;
15535                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15536                if (!app.serviceb) {
15537                    // This service isn't far enough down on the LRU list to
15538                    // normally be a B service, but if we are low on RAM and it
15539                    // is large we want to force it down since we would prefer to
15540                    // keep launcher over it.
15541                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15542                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15543                        app.serviceHighRam = true;
15544                        app.serviceb = true;
15545                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15546                    } else {
15547                        mNewNumAServiceProcs++;
15548                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15549                    }
15550                } else {
15551                    app.serviceHighRam = false;
15552                }
15553            }
15554            if (app.serviceb) {
15555                adj = ProcessList.SERVICE_B_ADJ;
15556            }
15557        }
15558
15559        app.curRawAdj = adj;
15560
15561        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15562        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15563        if (adj > app.maxAdj) {
15564            adj = app.maxAdj;
15565            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15566                schedGroup = Process.THREAD_GROUP_DEFAULT;
15567            }
15568        }
15569        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15570            app.keeping = true;
15571        }
15572
15573        // Do final modification to adj.  Everything we do between here and applying
15574        // the final setAdj must be done in this function, because we will also use
15575        // it when computing the final cached adj later.  Note that we don't need to
15576        // worry about this for max adj above, since max adj will always be used to
15577        // keep it out of the cached vaues.
15578        app.curAdj = app.modifyRawOomAdj(adj);
15579        app.curSchedGroup = schedGroup;
15580        app.curProcState = procState;
15581        app.foregroundActivities = foregroundActivities;
15582
15583        return app.curRawAdj;
15584    }
15585
15586    /**
15587     * Schedule PSS collection of a process.
15588     */
15589    void requestPssLocked(ProcessRecord proc, int procState) {
15590        if (mPendingPssProcesses.contains(proc)) {
15591            return;
15592        }
15593        if (mPendingPssProcesses.size() == 0) {
15594            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15595        }
15596        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15597        proc.pssProcState = procState;
15598        mPendingPssProcesses.add(proc);
15599    }
15600
15601    /**
15602     * Schedule PSS collection of all processes.
15603     */
15604    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15605        if (!always) {
15606            if (now < (mLastFullPssTime +
15607                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15608                return;
15609            }
15610        }
15611        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15612        mLastFullPssTime = now;
15613        mFullPssPending = true;
15614        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15615        mPendingPssProcesses.clear();
15616        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15617            ProcessRecord app = mLruProcesses.get(i);
15618            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15619                app.pssProcState = app.setProcState;
15620                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15621                        isSleeping(), now);
15622                mPendingPssProcesses.add(app);
15623            }
15624        }
15625        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15626    }
15627
15628    /**
15629     * Ask a given process to GC right now.
15630     */
15631    final void performAppGcLocked(ProcessRecord app) {
15632        try {
15633            app.lastRequestedGc = SystemClock.uptimeMillis();
15634            if (app.thread != null) {
15635                if (app.reportLowMemory) {
15636                    app.reportLowMemory = false;
15637                    app.thread.scheduleLowMemory();
15638                } else {
15639                    app.thread.processInBackground();
15640                }
15641            }
15642        } catch (Exception e) {
15643            // whatever.
15644        }
15645    }
15646
15647    /**
15648     * Returns true if things are idle enough to perform GCs.
15649     */
15650    private final boolean canGcNowLocked() {
15651        boolean processingBroadcasts = false;
15652        for (BroadcastQueue q : mBroadcastQueues) {
15653            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15654                processingBroadcasts = true;
15655            }
15656        }
15657        return !processingBroadcasts
15658                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15659    }
15660
15661    /**
15662     * Perform GCs on all processes that are waiting for it, but only
15663     * if things are idle.
15664     */
15665    final void performAppGcsLocked() {
15666        final int N = mProcessesToGc.size();
15667        if (N <= 0) {
15668            return;
15669        }
15670        if (canGcNowLocked()) {
15671            while (mProcessesToGc.size() > 0) {
15672                ProcessRecord proc = mProcessesToGc.remove(0);
15673                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15674                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15675                            <= SystemClock.uptimeMillis()) {
15676                        // To avoid spamming the system, we will GC processes one
15677                        // at a time, waiting a few seconds between each.
15678                        performAppGcLocked(proc);
15679                        scheduleAppGcsLocked();
15680                        return;
15681                    } else {
15682                        // It hasn't been long enough since we last GCed this
15683                        // process...  put it in the list to wait for its time.
15684                        addProcessToGcListLocked(proc);
15685                        break;
15686                    }
15687                }
15688            }
15689
15690            scheduleAppGcsLocked();
15691        }
15692    }
15693
15694    /**
15695     * If all looks good, perform GCs on all processes waiting for them.
15696     */
15697    final void performAppGcsIfAppropriateLocked() {
15698        if (canGcNowLocked()) {
15699            performAppGcsLocked();
15700            return;
15701        }
15702        // Still not idle, wait some more.
15703        scheduleAppGcsLocked();
15704    }
15705
15706    /**
15707     * Schedule the execution of all pending app GCs.
15708     */
15709    final void scheduleAppGcsLocked() {
15710        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15711
15712        if (mProcessesToGc.size() > 0) {
15713            // Schedule a GC for the time to the next process.
15714            ProcessRecord proc = mProcessesToGc.get(0);
15715            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15716
15717            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15718            long now = SystemClock.uptimeMillis();
15719            if (when < (now+GC_TIMEOUT)) {
15720                when = now + GC_TIMEOUT;
15721            }
15722            mHandler.sendMessageAtTime(msg, when);
15723        }
15724    }
15725
15726    /**
15727     * Add a process to the array of processes waiting to be GCed.  Keeps the
15728     * list in sorted order by the last GC time.  The process can't already be
15729     * on the list.
15730     */
15731    final void addProcessToGcListLocked(ProcessRecord proc) {
15732        boolean added = false;
15733        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15734            if (mProcessesToGc.get(i).lastRequestedGc <
15735                    proc.lastRequestedGc) {
15736                added = true;
15737                mProcessesToGc.add(i+1, proc);
15738                break;
15739            }
15740        }
15741        if (!added) {
15742            mProcessesToGc.add(0, proc);
15743        }
15744    }
15745
15746    /**
15747     * Set up to ask a process to GC itself.  This will either do it
15748     * immediately, or put it on the list of processes to gc the next
15749     * time things are idle.
15750     */
15751    final void scheduleAppGcLocked(ProcessRecord app) {
15752        long now = SystemClock.uptimeMillis();
15753        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15754            return;
15755        }
15756        if (!mProcessesToGc.contains(app)) {
15757            addProcessToGcListLocked(app);
15758            scheduleAppGcsLocked();
15759        }
15760    }
15761
15762    final void checkExcessivePowerUsageLocked(boolean doKills) {
15763        updateCpuStatsNow();
15764
15765        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15766        boolean doWakeKills = doKills;
15767        boolean doCpuKills = doKills;
15768        if (mLastPowerCheckRealtime == 0) {
15769            doWakeKills = false;
15770        }
15771        if (mLastPowerCheckUptime == 0) {
15772            doCpuKills = false;
15773        }
15774        if (stats.isScreenOn()) {
15775            doWakeKills = false;
15776        }
15777        final long curRealtime = SystemClock.elapsedRealtime();
15778        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15779        final long curUptime = SystemClock.uptimeMillis();
15780        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15781        mLastPowerCheckRealtime = curRealtime;
15782        mLastPowerCheckUptime = curUptime;
15783        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15784            doWakeKills = false;
15785        }
15786        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15787            doCpuKills = false;
15788        }
15789        int i = mLruProcesses.size();
15790        while (i > 0) {
15791            i--;
15792            ProcessRecord app = mLruProcesses.get(i);
15793            if (!app.keeping) {
15794                long wtime;
15795                synchronized (stats) {
15796                    wtime = stats.getProcessWakeTime(app.info.uid,
15797                            app.pid, curRealtime);
15798                }
15799                long wtimeUsed = wtime - app.lastWakeTime;
15800                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15801                if (DEBUG_POWER) {
15802                    StringBuilder sb = new StringBuilder(128);
15803                    sb.append("Wake for ");
15804                    app.toShortString(sb);
15805                    sb.append(": over ");
15806                    TimeUtils.formatDuration(realtimeSince, sb);
15807                    sb.append(" used ");
15808                    TimeUtils.formatDuration(wtimeUsed, sb);
15809                    sb.append(" (");
15810                    sb.append((wtimeUsed*100)/realtimeSince);
15811                    sb.append("%)");
15812                    Slog.i(TAG, sb.toString());
15813                    sb.setLength(0);
15814                    sb.append("CPU for ");
15815                    app.toShortString(sb);
15816                    sb.append(": over ");
15817                    TimeUtils.formatDuration(uptimeSince, sb);
15818                    sb.append(" used ");
15819                    TimeUtils.formatDuration(cputimeUsed, sb);
15820                    sb.append(" (");
15821                    sb.append((cputimeUsed*100)/uptimeSince);
15822                    sb.append("%)");
15823                    Slog.i(TAG, sb.toString());
15824                }
15825                // If a process has held a wake lock for more
15826                // than 50% of the time during this period,
15827                // that sounds bad.  Kill!
15828                if (doWakeKills && realtimeSince > 0
15829                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15830                    synchronized (stats) {
15831                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15832                                realtimeSince, wtimeUsed);
15833                    }
15834                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15835                            + " during " + realtimeSince);
15836                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15837                } else if (doCpuKills && uptimeSince > 0
15838                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15839                    synchronized (stats) {
15840                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15841                                uptimeSince, cputimeUsed);
15842                    }
15843                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15844                            + " during " + uptimeSince);
15845                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15846                } else {
15847                    app.lastWakeTime = wtime;
15848                    app.lastCpuTime = app.curCpuTime;
15849                }
15850            }
15851        }
15852    }
15853
15854    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15855            ProcessRecord TOP_APP, boolean doingAll, long now) {
15856        boolean success = true;
15857
15858        if (app.curRawAdj != app.setRawAdj) {
15859            if (wasKeeping && !app.keeping) {
15860                // This app is no longer something we want to keep.  Note
15861                // its current wake lock time to later know to kill it if
15862                // it is not behaving well.
15863                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15864                synchronized (stats) {
15865                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15866                            app.pid, SystemClock.elapsedRealtime());
15867                }
15868                app.lastCpuTime = app.curCpuTime;
15869            }
15870
15871            app.setRawAdj = app.curRawAdj;
15872        }
15873
15874        int changes = 0;
15875
15876        if (app.curAdj != app.setAdj) {
15877            ProcessList.setOomAdj(app.pid, app.curAdj);
15878            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15879                TAG, "Set " + app.pid + " " + app.processName +
15880                " adj " + app.curAdj + ": " + app.adjType);
15881            app.setAdj = app.curAdj;
15882        }
15883
15884        if (app.setSchedGroup != app.curSchedGroup) {
15885            app.setSchedGroup = app.curSchedGroup;
15886            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15887                    "Setting process group of " + app.processName
15888                    + " to " + app.curSchedGroup);
15889            if (app.waitingToKill != null &&
15890                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15891                killUnneededProcessLocked(app, app.waitingToKill);
15892                success = false;
15893            } else {
15894                if (true) {
15895                    long oldId = Binder.clearCallingIdentity();
15896                    try {
15897                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15898                    } catch (Exception e) {
15899                        Slog.w(TAG, "Failed setting process group of " + app.pid
15900                                + " to " + app.curSchedGroup);
15901                        e.printStackTrace();
15902                    } finally {
15903                        Binder.restoreCallingIdentity(oldId);
15904                    }
15905                } else {
15906                    if (app.thread != null) {
15907                        try {
15908                            app.thread.setSchedulingGroup(app.curSchedGroup);
15909                        } catch (RemoteException e) {
15910                        }
15911                    }
15912                }
15913                Process.setSwappiness(app.pid,
15914                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15915            }
15916        }
15917        if (app.repForegroundActivities != app.foregroundActivities) {
15918            app.repForegroundActivities = app.foregroundActivities;
15919            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15920        }
15921        if (app.repProcState != app.curProcState) {
15922            app.repProcState = app.curProcState;
15923            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15924            if (app.thread != null) {
15925                try {
15926                    if (false) {
15927                        //RuntimeException h = new RuntimeException("here");
15928                        Slog.i(TAG, "Sending new process state " + app.repProcState
15929                                + " to " + app /*, h*/);
15930                    }
15931                    app.thread.setProcessState(app.repProcState);
15932                } catch (RemoteException e) {
15933                }
15934            }
15935        }
15936        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15937                app.setProcState)) {
15938            app.lastStateTime = now;
15939            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15940                    isSleeping(), now);
15941            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15942                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15943                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15944                    + (app.nextPssTime-now) + ": " + app);
15945        } else {
15946            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15947                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15948                requestPssLocked(app, app.setProcState);
15949                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15950                        isSleeping(), now);
15951            } else if (false && DEBUG_PSS) {
15952                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15953            }
15954        }
15955        if (app.setProcState != app.curProcState) {
15956            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15957                    "Proc state change of " + app.processName
15958                    + " to " + app.curProcState);
15959            app.setProcState = app.curProcState;
15960            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15961                app.notCachedSinceIdle = false;
15962            }
15963            if (!doingAll) {
15964                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15965            } else {
15966                app.procStateChanged = true;
15967            }
15968        }
15969
15970        if (changes != 0) {
15971            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15972            int i = mPendingProcessChanges.size()-1;
15973            ProcessChangeItem item = null;
15974            while (i >= 0) {
15975                item = mPendingProcessChanges.get(i);
15976                if (item.pid == app.pid) {
15977                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15978                    break;
15979                }
15980                i--;
15981            }
15982            if (i < 0) {
15983                // No existing item in pending changes; need a new one.
15984                final int NA = mAvailProcessChanges.size();
15985                if (NA > 0) {
15986                    item = mAvailProcessChanges.remove(NA-1);
15987                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15988                } else {
15989                    item = new ProcessChangeItem();
15990                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15991                }
15992                item.changes = 0;
15993                item.pid = app.pid;
15994                item.uid = app.info.uid;
15995                if (mPendingProcessChanges.size() == 0) {
15996                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15997                            "*** Enqueueing dispatch processes changed!");
15998                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15999                }
16000                mPendingProcessChanges.add(item);
16001            }
16002            item.changes |= changes;
16003            item.processState = app.repProcState;
16004            item.foregroundActivities = app.repForegroundActivities;
16005            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16006                    + Integer.toHexString(System.identityHashCode(item))
16007                    + " " + app.toShortString() + ": changes=" + item.changes
16008                    + " procState=" + item.processState
16009                    + " foreground=" + item.foregroundActivities
16010                    + " type=" + app.adjType + " source=" + app.adjSource
16011                    + " target=" + app.adjTarget);
16012        }
16013
16014        return success;
16015    }
16016
16017    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16018        if (proc.thread != null && proc.baseProcessTracker != null) {
16019            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16020        }
16021    }
16022
16023    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16024            ProcessRecord TOP_APP, boolean doingAll, long now) {
16025        if (app.thread == null) {
16026            return false;
16027        }
16028
16029        final boolean wasKeeping = app.keeping;
16030
16031        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16032
16033        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16034    }
16035
16036    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16037            boolean oomAdj) {
16038        if (isForeground != proc.foregroundServices) {
16039            proc.foregroundServices = isForeground;
16040            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16041                    proc.info.uid);
16042            if (isForeground) {
16043                if (curProcs == null) {
16044                    curProcs = new ArrayList<ProcessRecord>();
16045                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16046                }
16047                if (!curProcs.contains(proc)) {
16048                    curProcs.add(proc);
16049                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16050                            proc.info.packageName, proc.info.uid);
16051                }
16052            } else {
16053                if (curProcs != null) {
16054                    if (curProcs.remove(proc)) {
16055                        mBatteryStatsService.noteEvent(
16056                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16057                                proc.info.packageName, proc.info.uid);
16058                        if (curProcs.size() <= 0) {
16059                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16060                        }
16061                    }
16062                }
16063            }
16064            if (oomAdj) {
16065                updateOomAdjLocked();
16066            }
16067        }
16068    }
16069
16070    private final ActivityRecord resumedAppLocked() {
16071        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16072        String pkg;
16073        int uid;
16074        if (act != null && !act.sleeping) {
16075            pkg = act.packageName;
16076            uid = act.info.applicationInfo.uid;
16077        } else {
16078            pkg = null;
16079            uid = -1;
16080        }
16081        // Has the UID or resumed package name changed?
16082        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16083                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16084            if (mCurResumedPackage != null) {
16085                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16086                        mCurResumedPackage, mCurResumedUid);
16087            }
16088            mCurResumedPackage = pkg;
16089            mCurResumedUid = uid;
16090            if (mCurResumedPackage != null) {
16091                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16092                        mCurResumedPackage, mCurResumedUid);
16093            }
16094        }
16095        return act;
16096    }
16097
16098    final boolean updateOomAdjLocked(ProcessRecord app) {
16099        final ActivityRecord TOP_ACT = resumedAppLocked();
16100        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16101        final boolean wasCached = app.cached;
16102
16103        mAdjSeq++;
16104
16105        // This is the desired cached adjusment we want to tell it to use.
16106        // If our app is currently cached, we know it, and that is it.  Otherwise,
16107        // we don't know it yet, and it needs to now be cached we will then
16108        // need to do a complete oom adj.
16109        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16110                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16111        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16112                SystemClock.uptimeMillis());
16113        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16114            // Changed to/from cached state, so apps after it in the LRU
16115            // list may also be changed.
16116            updateOomAdjLocked();
16117        }
16118        return success;
16119    }
16120
16121    final void updateOomAdjLocked() {
16122        final ActivityRecord TOP_ACT = resumedAppLocked();
16123        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16124        final long now = SystemClock.uptimeMillis();
16125        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16126        final int N = mLruProcesses.size();
16127
16128        if (false) {
16129            RuntimeException e = new RuntimeException();
16130            e.fillInStackTrace();
16131            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16132        }
16133
16134        mAdjSeq++;
16135        mNewNumServiceProcs = 0;
16136        mNewNumAServiceProcs = 0;
16137
16138        final int emptyProcessLimit;
16139        final int cachedProcessLimit;
16140        if (mProcessLimit <= 0) {
16141            emptyProcessLimit = cachedProcessLimit = 0;
16142        } else if (mProcessLimit == 1) {
16143            emptyProcessLimit = 1;
16144            cachedProcessLimit = 0;
16145        } else {
16146            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16147            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16148        }
16149
16150        // Let's determine how many processes we have running vs.
16151        // how many slots we have for background processes; we may want
16152        // to put multiple processes in a slot of there are enough of
16153        // them.
16154        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16155                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16156        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16157        if (numEmptyProcs > cachedProcessLimit) {
16158            // If there are more empty processes than our limit on cached
16159            // processes, then use the cached process limit for the factor.
16160            // This ensures that the really old empty processes get pushed
16161            // down to the bottom, so if we are running low on memory we will
16162            // have a better chance at keeping around more cached processes
16163            // instead of a gazillion empty processes.
16164            numEmptyProcs = cachedProcessLimit;
16165        }
16166        int emptyFactor = numEmptyProcs/numSlots;
16167        if (emptyFactor < 1) emptyFactor = 1;
16168        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16169        if (cachedFactor < 1) cachedFactor = 1;
16170        int stepCached = 0;
16171        int stepEmpty = 0;
16172        int numCached = 0;
16173        int numEmpty = 0;
16174        int numTrimming = 0;
16175
16176        mNumNonCachedProcs = 0;
16177        mNumCachedHiddenProcs = 0;
16178
16179        // First update the OOM adjustment for each of the
16180        // application processes based on their current state.
16181        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16182        int nextCachedAdj = curCachedAdj+1;
16183        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16184        int nextEmptyAdj = curEmptyAdj+2;
16185        for (int i=N-1; i>=0; i--) {
16186            ProcessRecord app = mLruProcesses.get(i);
16187            if (!app.killedByAm && app.thread != null) {
16188                app.procStateChanged = false;
16189                final boolean wasKeeping = app.keeping;
16190                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16191
16192                // If we haven't yet assigned the final cached adj
16193                // to the process, do that now.
16194                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16195                    switch (app.curProcState) {
16196                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16197                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16198                            // This process is a cached process holding activities...
16199                            // assign it the next cached value for that type, and then
16200                            // step that cached level.
16201                            app.curRawAdj = curCachedAdj;
16202                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16203                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16204                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16205                                    + ")");
16206                            if (curCachedAdj != nextCachedAdj) {
16207                                stepCached++;
16208                                if (stepCached >= cachedFactor) {
16209                                    stepCached = 0;
16210                                    curCachedAdj = nextCachedAdj;
16211                                    nextCachedAdj += 2;
16212                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16213                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16214                                    }
16215                                }
16216                            }
16217                            break;
16218                        default:
16219                            // For everything else, assign next empty cached process
16220                            // level and bump that up.  Note that this means that
16221                            // long-running services that have dropped down to the
16222                            // cached level will be treated as empty (since their process
16223                            // state is still as a service), which is what we want.
16224                            app.curRawAdj = curEmptyAdj;
16225                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16226                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16227                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16228                                    + ")");
16229                            if (curEmptyAdj != nextEmptyAdj) {
16230                                stepEmpty++;
16231                                if (stepEmpty >= emptyFactor) {
16232                                    stepEmpty = 0;
16233                                    curEmptyAdj = nextEmptyAdj;
16234                                    nextEmptyAdj += 2;
16235                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16236                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16237                                    }
16238                                }
16239                            }
16240                            break;
16241                    }
16242                }
16243
16244                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16245
16246                // Count the number of process types.
16247                switch (app.curProcState) {
16248                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16249                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16250                        mNumCachedHiddenProcs++;
16251                        numCached++;
16252                        if (numCached > cachedProcessLimit) {
16253                            killUnneededProcessLocked(app, "cached #" + numCached);
16254                        }
16255                        break;
16256                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16257                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16258                                && app.lastActivityTime < oldTime) {
16259                            killUnneededProcessLocked(app, "empty for "
16260                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16261                                    / 1000) + "s");
16262                        } else {
16263                            numEmpty++;
16264                            if (numEmpty > emptyProcessLimit) {
16265                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16266                            }
16267                        }
16268                        break;
16269                    default:
16270                        mNumNonCachedProcs++;
16271                        break;
16272                }
16273
16274                if (app.isolated && app.services.size() <= 0) {
16275                    // If this is an isolated process, and there are no
16276                    // services running in it, then the process is no longer
16277                    // needed.  We agressively kill these because we can by
16278                    // definition not re-use the same process again, and it is
16279                    // good to avoid having whatever code was running in them
16280                    // left sitting around after no longer needed.
16281                    killUnneededProcessLocked(app, "isolated not needed");
16282                }
16283
16284                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16285                        && !app.killedByAm) {
16286                    numTrimming++;
16287                }
16288            }
16289        }
16290
16291        mNumServiceProcs = mNewNumServiceProcs;
16292
16293        // Now determine the memory trimming level of background processes.
16294        // Unfortunately we need to start at the back of the list to do this
16295        // properly.  We only do this if the number of background apps we
16296        // are managing to keep around is less than half the maximum we desire;
16297        // if we are keeping a good number around, we'll let them use whatever
16298        // memory they want.
16299        final int numCachedAndEmpty = numCached + numEmpty;
16300        int memFactor;
16301        if (numCached <= ProcessList.TRIM_CACHED_APPS
16302                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16303            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16304                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16305            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16306                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16307            } else {
16308                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16309            }
16310        } else {
16311            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16312        }
16313        // We always allow the memory level to go up (better).  We only allow it to go
16314        // down if we are in a state where that is allowed, *and* the total number of processes
16315        // has gone down since last time.
16316        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16317                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16318                + " last=" + mLastNumProcesses);
16319        if (memFactor > mLastMemoryLevel) {
16320            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16321                memFactor = mLastMemoryLevel;
16322                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16323            }
16324        }
16325        mLastMemoryLevel = memFactor;
16326        mLastNumProcesses = mLruProcesses.size();
16327        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16328        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16329        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16330            if (mLowRamStartTime == 0) {
16331                mLowRamStartTime = now;
16332            }
16333            int step = 0;
16334            int fgTrimLevel;
16335            switch (memFactor) {
16336                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16337                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16338                    break;
16339                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16340                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16341                    break;
16342                default:
16343                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16344                    break;
16345            }
16346            int factor = numTrimming/3;
16347            int minFactor = 2;
16348            if (mHomeProcess != null) minFactor++;
16349            if (mPreviousProcess != null) minFactor++;
16350            if (factor < minFactor) factor = minFactor;
16351            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16352            for (int i=N-1; i>=0; i--) {
16353                ProcessRecord app = mLruProcesses.get(i);
16354                if (allChanged || app.procStateChanged) {
16355                    setProcessTrackerState(app, trackerMemFactor, now);
16356                    app.procStateChanged = false;
16357                }
16358                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16359                        && !app.killedByAm) {
16360                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16361                        try {
16362                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16363                                    "Trimming memory of " + app.processName
16364                                    + " to " + curLevel);
16365                            app.thread.scheduleTrimMemory(curLevel);
16366                        } catch (RemoteException e) {
16367                        }
16368                        if (false) {
16369                            // For now we won't do this; our memory trimming seems
16370                            // to be good enough at this point that destroying
16371                            // activities causes more harm than good.
16372                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16373                                    && app != mHomeProcess && app != mPreviousProcess) {
16374                                // Need to do this on its own message because the stack may not
16375                                // be in a consistent state at this point.
16376                                // For these apps we will also finish their activities
16377                                // to help them free memory.
16378                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16379                            }
16380                        }
16381                    }
16382                    app.trimMemoryLevel = curLevel;
16383                    step++;
16384                    if (step >= factor) {
16385                        step = 0;
16386                        switch (curLevel) {
16387                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16388                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16389                                break;
16390                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16391                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16392                                break;
16393                        }
16394                    }
16395                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16396                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16397                            && app.thread != null) {
16398                        try {
16399                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16400                                    "Trimming memory of heavy-weight " + app.processName
16401                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16402                            app.thread.scheduleTrimMemory(
16403                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16404                        } catch (RemoteException e) {
16405                        }
16406                    }
16407                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16408                } else {
16409                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16410                            || app.systemNoUi) && app.pendingUiClean) {
16411                        // If this application is now in the background and it
16412                        // had done UI, then give it the special trim level to
16413                        // have it free UI resources.
16414                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16415                        if (app.trimMemoryLevel < level && app.thread != null) {
16416                            try {
16417                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16418                                        "Trimming memory of bg-ui " + app.processName
16419                                        + " to " + level);
16420                                app.thread.scheduleTrimMemory(level);
16421                            } catch (RemoteException e) {
16422                            }
16423                        }
16424                        app.pendingUiClean = false;
16425                    }
16426                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16427                        try {
16428                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16429                                    "Trimming memory of fg " + app.processName
16430                                    + " to " + fgTrimLevel);
16431                            app.thread.scheduleTrimMemory(fgTrimLevel);
16432                        } catch (RemoteException e) {
16433                        }
16434                    }
16435                    app.trimMemoryLevel = fgTrimLevel;
16436                }
16437            }
16438        } else {
16439            if (mLowRamStartTime != 0) {
16440                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16441                mLowRamStartTime = 0;
16442            }
16443            for (int i=N-1; i>=0; i--) {
16444                ProcessRecord app = mLruProcesses.get(i);
16445                if (allChanged || app.procStateChanged) {
16446                    setProcessTrackerState(app, trackerMemFactor, now);
16447                    app.procStateChanged = false;
16448                }
16449                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16450                        || app.systemNoUi) && app.pendingUiClean) {
16451                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16452                            && app.thread != null) {
16453                        try {
16454                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16455                                    "Trimming memory of ui hidden " + app.processName
16456                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16457                            app.thread.scheduleTrimMemory(
16458                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16459                        } catch (RemoteException e) {
16460                        }
16461                    }
16462                    app.pendingUiClean = false;
16463                }
16464                app.trimMemoryLevel = 0;
16465            }
16466        }
16467
16468        if (mAlwaysFinishActivities) {
16469            // Need to do this on its own message because the stack may not
16470            // be in a consistent state at this point.
16471            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16472        }
16473
16474        if (allChanged) {
16475            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16476        }
16477
16478        if (mProcessStats.shouldWriteNowLocked(now)) {
16479            mHandler.post(new Runnable() {
16480                @Override public void run() {
16481                    synchronized (ActivityManagerService.this) {
16482                        mProcessStats.writeStateAsyncLocked();
16483                    }
16484                }
16485            });
16486        }
16487
16488        if (DEBUG_OOM_ADJ) {
16489            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16490        }
16491    }
16492
16493    final void trimApplications() {
16494        synchronized (this) {
16495            int i;
16496
16497            // First remove any unused application processes whose package
16498            // has been removed.
16499            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16500                final ProcessRecord app = mRemovedProcesses.get(i);
16501                if (app.activities.size() == 0
16502                        && app.curReceiver == null && app.services.size() == 0) {
16503                    Slog.i(
16504                        TAG, "Exiting empty application process "
16505                        + app.processName + " ("
16506                        + (app.thread != null ? app.thread.asBinder() : null)
16507                        + ")\n");
16508                    if (app.pid > 0 && app.pid != MY_PID) {
16509                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16510                                app.processName, app.setAdj, "empty");
16511                        app.killedByAm = true;
16512                        Process.killProcessQuiet(app.pid);
16513                    } else {
16514                        try {
16515                            app.thread.scheduleExit();
16516                        } catch (Exception e) {
16517                            // Ignore exceptions.
16518                        }
16519                    }
16520                    cleanUpApplicationRecordLocked(app, false, true, -1);
16521                    mRemovedProcesses.remove(i);
16522
16523                    if (app.persistent) {
16524                        if (app.persistent) {
16525                            addAppLocked(app.info, false, null /* ABI override */);
16526                        }
16527                    }
16528                }
16529            }
16530
16531            // Now update the oom adj for all processes.
16532            updateOomAdjLocked();
16533        }
16534    }
16535
16536    /** This method sends the specified signal to each of the persistent apps */
16537    public void signalPersistentProcesses(int sig) throws RemoteException {
16538        if (sig != Process.SIGNAL_USR1) {
16539            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16540        }
16541
16542        synchronized (this) {
16543            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16544                    != PackageManager.PERMISSION_GRANTED) {
16545                throw new SecurityException("Requires permission "
16546                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16547            }
16548
16549            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16550                ProcessRecord r = mLruProcesses.get(i);
16551                if (r.thread != null && r.persistent) {
16552                    Process.sendSignal(r.pid, sig);
16553                }
16554            }
16555        }
16556    }
16557
16558    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16559        if (proc == null || proc == mProfileProc) {
16560            proc = mProfileProc;
16561            path = mProfileFile;
16562            profileType = mProfileType;
16563            clearProfilerLocked();
16564        }
16565        if (proc == null) {
16566            return;
16567        }
16568        try {
16569            proc.thread.profilerControl(false, path, null, profileType);
16570        } catch (RemoteException e) {
16571            throw new IllegalStateException("Process disappeared");
16572        }
16573    }
16574
16575    private void clearProfilerLocked() {
16576        if (mProfileFd != null) {
16577            try {
16578                mProfileFd.close();
16579            } catch (IOException e) {
16580            }
16581        }
16582        mProfileApp = null;
16583        mProfileProc = null;
16584        mProfileFile = null;
16585        mProfileType = 0;
16586        mAutoStopProfiler = false;
16587    }
16588
16589    public boolean profileControl(String process, int userId, boolean start,
16590            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16591
16592        try {
16593            synchronized (this) {
16594                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16595                // its own permission.
16596                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16597                        != PackageManager.PERMISSION_GRANTED) {
16598                    throw new SecurityException("Requires permission "
16599                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16600                }
16601
16602                if (start && fd == null) {
16603                    throw new IllegalArgumentException("null fd");
16604                }
16605
16606                ProcessRecord proc = null;
16607                if (process != null) {
16608                    proc = findProcessLocked(process, userId, "profileControl");
16609                }
16610
16611                if (start && (proc == null || proc.thread == null)) {
16612                    throw new IllegalArgumentException("Unknown process: " + process);
16613                }
16614
16615                if (start) {
16616                    stopProfilerLocked(null, null, 0);
16617                    setProfileApp(proc.info, proc.processName, path, fd, false);
16618                    mProfileProc = proc;
16619                    mProfileType = profileType;
16620                    try {
16621                        fd = fd.dup();
16622                    } catch (IOException e) {
16623                        fd = null;
16624                    }
16625                    proc.thread.profilerControl(start, path, fd, profileType);
16626                    fd = null;
16627                    mProfileFd = null;
16628                } else {
16629                    stopProfilerLocked(proc, path, profileType);
16630                    if (fd != null) {
16631                        try {
16632                            fd.close();
16633                        } catch (IOException e) {
16634                        }
16635                    }
16636                }
16637
16638                return true;
16639            }
16640        } catch (RemoteException e) {
16641            throw new IllegalStateException("Process disappeared");
16642        } finally {
16643            if (fd != null) {
16644                try {
16645                    fd.close();
16646                } catch (IOException e) {
16647                }
16648            }
16649        }
16650    }
16651
16652    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16653        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16654                userId, true, true, callName, null);
16655        ProcessRecord proc = null;
16656        try {
16657            int pid = Integer.parseInt(process);
16658            synchronized (mPidsSelfLocked) {
16659                proc = mPidsSelfLocked.get(pid);
16660            }
16661        } catch (NumberFormatException e) {
16662        }
16663
16664        if (proc == null) {
16665            ArrayMap<String, SparseArray<ProcessRecord>> all
16666                    = mProcessNames.getMap();
16667            SparseArray<ProcessRecord> procs = all.get(process);
16668            if (procs != null && procs.size() > 0) {
16669                proc = procs.valueAt(0);
16670                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16671                    for (int i=1; i<procs.size(); i++) {
16672                        ProcessRecord thisProc = procs.valueAt(i);
16673                        if (thisProc.userId == userId) {
16674                            proc = thisProc;
16675                            break;
16676                        }
16677                    }
16678                }
16679            }
16680        }
16681
16682        return proc;
16683    }
16684
16685    public boolean dumpHeap(String process, int userId, boolean managed,
16686            String path, ParcelFileDescriptor fd) throws RemoteException {
16687
16688        try {
16689            synchronized (this) {
16690                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16691                // its own permission (same as profileControl).
16692                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16693                        != PackageManager.PERMISSION_GRANTED) {
16694                    throw new SecurityException("Requires permission "
16695                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16696                }
16697
16698                if (fd == null) {
16699                    throw new IllegalArgumentException("null fd");
16700                }
16701
16702                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16703                if (proc == null || proc.thread == null) {
16704                    throw new IllegalArgumentException("Unknown process: " + process);
16705                }
16706
16707                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16708                if (!isDebuggable) {
16709                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16710                        throw new SecurityException("Process not debuggable: " + proc);
16711                    }
16712                }
16713
16714                proc.thread.dumpHeap(managed, path, fd);
16715                fd = null;
16716                return true;
16717            }
16718        } catch (RemoteException e) {
16719            throw new IllegalStateException("Process disappeared");
16720        } finally {
16721            if (fd != null) {
16722                try {
16723                    fd.close();
16724                } catch (IOException e) {
16725                }
16726            }
16727        }
16728    }
16729
16730    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16731    public void monitor() {
16732        synchronized (this) { }
16733    }
16734
16735    void onCoreSettingsChange(Bundle settings) {
16736        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16737            ProcessRecord processRecord = mLruProcesses.get(i);
16738            try {
16739                if (processRecord.thread != null) {
16740                    processRecord.thread.setCoreSettings(settings);
16741                }
16742            } catch (RemoteException re) {
16743                /* ignore */
16744            }
16745        }
16746    }
16747
16748    // Multi-user methods
16749
16750    /**
16751     * Start user, if its not already running, but don't bring it to foreground.
16752     */
16753    @Override
16754    public boolean startUserInBackground(final int userId) {
16755        return startUser(userId, /* foreground */ false);
16756    }
16757
16758    /**
16759     * Refreshes the list of users related to the current user when either a
16760     * user switch happens or when a new related user is started in the
16761     * background.
16762     */
16763    private void updateCurrentProfileIdsLocked() {
16764        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16765                mCurrentUserId, false /* enabledOnly */);
16766        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16767        for (int i = 0; i < currentProfileIds.length; i++) {
16768            currentProfileIds[i] = profiles.get(i).id;
16769        }
16770        mCurrentProfileIds = currentProfileIds;
16771    }
16772
16773    private Set getProfileIdsLocked(int userId) {
16774        Set userIds = new HashSet<Integer>();
16775        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16776                userId, false /* enabledOnly */);
16777        for (UserInfo user : profiles) {
16778            userIds.add(Integer.valueOf(user.id));
16779        }
16780        return userIds;
16781    }
16782
16783    @Override
16784    public boolean switchUser(final int userId) {
16785        return startUser(userId, /* foregound */ true);
16786    }
16787
16788    private boolean startUser(final int userId, boolean foreground) {
16789        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16790                != PackageManager.PERMISSION_GRANTED) {
16791            String msg = "Permission Denial: switchUser() from pid="
16792                    + Binder.getCallingPid()
16793                    + ", uid=" + Binder.getCallingUid()
16794                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16795            Slog.w(TAG, msg);
16796            throw new SecurityException(msg);
16797        }
16798
16799        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16800
16801        final long ident = Binder.clearCallingIdentity();
16802        try {
16803            synchronized (this) {
16804                final int oldUserId = mCurrentUserId;
16805                if (oldUserId == userId) {
16806                    return true;
16807                }
16808
16809                mStackSupervisor.setLockTaskModeLocked(null, false);
16810
16811                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16812                if (userInfo == null) {
16813                    Slog.w(TAG, "No user info for user #" + userId);
16814                    return false;
16815                }
16816
16817                if (foreground) {
16818                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16819                            R.anim.screen_user_enter);
16820                }
16821
16822                boolean needStart = false;
16823
16824                // If the user we are switching to is not currently started, then
16825                // we need to start it now.
16826                if (mStartedUsers.get(userId) == null) {
16827                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16828                    updateStartedUserArrayLocked();
16829                    needStart = true;
16830                }
16831
16832                final Integer userIdInt = Integer.valueOf(userId);
16833                mUserLru.remove(userIdInt);
16834                mUserLru.add(userIdInt);
16835
16836                if (foreground) {
16837                    mCurrentUserId = userId;
16838                    updateCurrentProfileIdsLocked();
16839                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16840                    // Once the internal notion of the active user has switched, we lock the device
16841                    // with the option to show the user switcher on the keyguard.
16842                    mWindowManager.lockNow(null);
16843                } else {
16844                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16845                    updateCurrentProfileIdsLocked();
16846                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16847                    mUserLru.remove(currentUserIdInt);
16848                    mUserLru.add(currentUserIdInt);
16849                }
16850
16851                final UserStartedState uss = mStartedUsers.get(userId);
16852
16853                // Make sure user is in the started state.  If it is currently
16854                // stopping, we need to knock that off.
16855                if (uss.mState == UserStartedState.STATE_STOPPING) {
16856                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16857                    // so we can just fairly silently bring the user back from
16858                    // the almost-dead.
16859                    uss.mState = UserStartedState.STATE_RUNNING;
16860                    updateStartedUserArrayLocked();
16861                    needStart = true;
16862                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16863                    // This means ACTION_SHUTDOWN has been sent, so we will
16864                    // need to treat this as a new boot of the user.
16865                    uss.mState = UserStartedState.STATE_BOOTING;
16866                    updateStartedUserArrayLocked();
16867                    needStart = true;
16868                }
16869
16870                if (uss.mState == UserStartedState.STATE_BOOTING) {
16871                    // Booting up a new user, need to tell system services about it.
16872                    // Note that this is on the same handler as scheduling of broadcasts,
16873                    // which is important because it needs to go first.
16874                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16875                }
16876
16877                if (foreground) {
16878                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16879                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16880                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16881                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16882                            oldUserId, userId, uss));
16883                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16884                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16885                }
16886
16887                if (needStart) {
16888                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16889                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16890                            | Intent.FLAG_RECEIVER_FOREGROUND);
16891                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16892                    broadcastIntentLocked(null, null, intent,
16893                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16894                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16895                }
16896
16897                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16898                    if (userId != UserHandle.USER_OWNER) {
16899                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16900                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16901                        broadcastIntentLocked(null, null, intent, null,
16902                                new IIntentReceiver.Stub() {
16903                                    public void performReceive(Intent intent, int resultCode,
16904                                            String data, Bundle extras, boolean ordered,
16905                                            boolean sticky, int sendingUser) {
16906                                        userInitialized(uss, userId);
16907                                    }
16908                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16909                                true, false, MY_PID, Process.SYSTEM_UID,
16910                                userId);
16911                        uss.initializing = true;
16912                    } else {
16913                        getUserManagerLocked().makeInitialized(userInfo.id);
16914                    }
16915                }
16916
16917                if (foreground) {
16918                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16919                    if (homeInFront) {
16920                        startHomeActivityLocked(userId);
16921                    } else {
16922                        mStackSupervisor.resumeTopActivitiesLocked();
16923                    }
16924                    EventLogTags.writeAmSwitchUser(userId);
16925                    getUserManagerLocked().userForeground(userId);
16926                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16927                } else {
16928                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16929                }
16930
16931                if (needStart) {
16932                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16933                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16934                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16935                    broadcastIntentLocked(null, null, intent,
16936                            null, new IIntentReceiver.Stub() {
16937                                @Override
16938                                public void performReceive(Intent intent, int resultCode, String data,
16939                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16940                                        throws RemoteException {
16941                                }
16942                            }, 0, null, null,
16943                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16944                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16945                }
16946            }
16947        } finally {
16948            Binder.restoreCallingIdentity(ident);
16949        }
16950
16951        return true;
16952    }
16953
16954    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16955        long ident = Binder.clearCallingIdentity();
16956        try {
16957            Intent intent;
16958            if (oldUserId >= 0) {
16959                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16960                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16961                        | Intent.FLAG_RECEIVER_FOREGROUND);
16962                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16963                broadcastIntentLocked(null, null, intent,
16964                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16965                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16966            }
16967            if (newUserId >= 0) {
16968                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16969                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16970                        | Intent.FLAG_RECEIVER_FOREGROUND);
16971                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16972                broadcastIntentLocked(null, null, intent,
16973                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16974                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16975                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16976                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16977                        | Intent.FLAG_RECEIVER_FOREGROUND);
16978                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16979                broadcastIntentLocked(null, null, intent,
16980                        null, null, 0, null, null,
16981                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16982                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16983            }
16984        } finally {
16985            Binder.restoreCallingIdentity(ident);
16986        }
16987    }
16988
16989    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16990            final int newUserId) {
16991        final int N = mUserSwitchObservers.beginBroadcast();
16992        if (N > 0) {
16993            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16994                int mCount = 0;
16995                @Override
16996                public void sendResult(Bundle data) throws RemoteException {
16997                    synchronized (ActivityManagerService.this) {
16998                        if (mCurUserSwitchCallback == this) {
16999                            mCount++;
17000                            if (mCount == N) {
17001                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17002                            }
17003                        }
17004                    }
17005                }
17006            };
17007            synchronized (this) {
17008                uss.switching = true;
17009                mCurUserSwitchCallback = callback;
17010            }
17011            for (int i=0; i<N; i++) {
17012                try {
17013                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17014                            newUserId, callback);
17015                } catch (RemoteException e) {
17016                }
17017            }
17018        } else {
17019            synchronized (this) {
17020                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17021            }
17022        }
17023        mUserSwitchObservers.finishBroadcast();
17024    }
17025
17026    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17027        synchronized (this) {
17028            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17029            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17030        }
17031    }
17032
17033    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17034        mCurUserSwitchCallback = null;
17035        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17036        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17037                oldUserId, newUserId, uss));
17038    }
17039
17040    void userInitialized(UserStartedState uss, int newUserId) {
17041        completeSwitchAndInitalize(uss, newUserId, true, false);
17042    }
17043
17044    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17045        completeSwitchAndInitalize(uss, newUserId, false, true);
17046    }
17047
17048    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17049            boolean clearInitializing, boolean clearSwitching) {
17050        boolean unfrozen = false;
17051        synchronized (this) {
17052            if (clearInitializing) {
17053                uss.initializing = false;
17054                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17055            }
17056            if (clearSwitching) {
17057                uss.switching = false;
17058            }
17059            if (!uss.switching && !uss.initializing) {
17060                mWindowManager.stopFreezingScreen();
17061                unfrozen = true;
17062            }
17063        }
17064        if (unfrozen) {
17065            final int N = mUserSwitchObservers.beginBroadcast();
17066            for (int i=0; i<N; i++) {
17067                try {
17068                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17069                } catch (RemoteException e) {
17070                }
17071            }
17072            mUserSwitchObservers.finishBroadcast();
17073        }
17074    }
17075
17076    void scheduleStartProfilesLocked() {
17077        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17078            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17079                    DateUtils.SECOND_IN_MILLIS);
17080        }
17081    }
17082
17083    void startProfilesLocked() {
17084        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17085        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17086                mCurrentUserId, false /* enabledOnly */);
17087        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17088        for (UserInfo user : profiles) {
17089            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17090                    && user.id != mCurrentUserId) {
17091                toStart.add(user);
17092            }
17093        }
17094        final int n = toStart.size();
17095        int i = 0;
17096        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17097            startUserInBackground(toStart.get(i).id);
17098        }
17099        if (i < n) {
17100            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17101        }
17102    }
17103
17104    void finishUserBoot(UserStartedState uss) {
17105        synchronized (this) {
17106            if (uss.mState == UserStartedState.STATE_BOOTING
17107                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17108                uss.mState = UserStartedState.STATE_RUNNING;
17109                final int userId = uss.mHandle.getIdentifier();
17110                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17111                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17112                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17113                broadcastIntentLocked(null, null, intent,
17114                        null, null, 0, null, null,
17115                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17116                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17117            }
17118        }
17119    }
17120
17121    void finishUserSwitch(UserStartedState uss) {
17122        synchronized (this) {
17123            finishUserBoot(uss);
17124
17125            startProfilesLocked();
17126
17127            int num = mUserLru.size();
17128            int i = 0;
17129            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17130                Integer oldUserId = mUserLru.get(i);
17131                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17132                if (oldUss == null) {
17133                    // Shouldn't happen, but be sane if it does.
17134                    mUserLru.remove(i);
17135                    num--;
17136                    continue;
17137                }
17138                if (oldUss.mState == UserStartedState.STATE_STOPPING
17139                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17140                    // This user is already stopping, doesn't count.
17141                    num--;
17142                    i++;
17143                    continue;
17144                }
17145                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17146                    // Owner and current can't be stopped, but count as running.
17147                    i++;
17148                    continue;
17149                }
17150                // This is a user to be stopped.
17151                stopUserLocked(oldUserId, null);
17152                num--;
17153                i++;
17154            }
17155        }
17156    }
17157
17158    @Override
17159    public int stopUser(final int userId, final IStopUserCallback callback) {
17160        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17161                != PackageManager.PERMISSION_GRANTED) {
17162            String msg = "Permission Denial: switchUser() from pid="
17163                    + Binder.getCallingPid()
17164                    + ", uid=" + Binder.getCallingUid()
17165                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17166            Slog.w(TAG, msg);
17167            throw new SecurityException(msg);
17168        }
17169        if (userId <= 0) {
17170            throw new IllegalArgumentException("Can't stop primary user " + userId);
17171        }
17172        synchronized (this) {
17173            return stopUserLocked(userId, callback);
17174        }
17175    }
17176
17177    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17178        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17179        if (mCurrentUserId == userId) {
17180            return ActivityManager.USER_OP_IS_CURRENT;
17181        }
17182
17183        final UserStartedState uss = mStartedUsers.get(userId);
17184        if (uss == null) {
17185            // User is not started, nothing to do...  but we do need to
17186            // callback if requested.
17187            if (callback != null) {
17188                mHandler.post(new Runnable() {
17189                    @Override
17190                    public void run() {
17191                        try {
17192                            callback.userStopped(userId);
17193                        } catch (RemoteException e) {
17194                        }
17195                    }
17196                });
17197            }
17198            return ActivityManager.USER_OP_SUCCESS;
17199        }
17200
17201        if (callback != null) {
17202            uss.mStopCallbacks.add(callback);
17203        }
17204
17205        if (uss.mState != UserStartedState.STATE_STOPPING
17206                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17207            uss.mState = UserStartedState.STATE_STOPPING;
17208            updateStartedUserArrayLocked();
17209
17210            long ident = Binder.clearCallingIdentity();
17211            try {
17212                // We are going to broadcast ACTION_USER_STOPPING and then
17213                // once that is done send a final ACTION_SHUTDOWN and then
17214                // stop the user.
17215                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17216                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17217                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17218                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17219                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17220                // This is the result receiver for the final shutdown broadcast.
17221                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17222                    @Override
17223                    public void performReceive(Intent intent, int resultCode, String data,
17224                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17225                        finishUserStop(uss);
17226                    }
17227                };
17228                // This is the result receiver for the initial stopping broadcast.
17229                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17230                    @Override
17231                    public void performReceive(Intent intent, int resultCode, String data,
17232                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17233                        // On to the next.
17234                        synchronized (ActivityManagerService.this) {
17235                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17236                                // Whoops, we are being started back up.  Abort, abort!
17237                                return;
17238                            }
17239                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17240                        }
17241                        mSystemServiceManager.stopUser(userId);
17242                        broadcastIntentLocked(null, null, shutdownIntent,
17243                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17244                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17245                    }
17246                };
17247                // Kick things off.
17248                broadcastIntentLocked(null, null, stoppingIntent,
17249                        null, stoppingReceiver, 0, null, null,
17250                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17251                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17252            } finally {
17253                Binder.restoreCallingIdentity(ident);
17254            }
17255        }
17256
17257        return ActivityManager.USER_OP_SUCCESS;
17258    }
17259
17260    void finishUserStop(UserStartedState uss) {
17261        final int userId = uss.mHandle.getIdentifier();
17262        boolean stopped;
17263        ArrayList<IStopUserCallback> callbacks;
17264        synchronized (this) {
17265            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17266            if (mStartedUsers.get(userId) != uss) {
17267                stopped = false;
17268            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17269                stopped = false;
17270            } else {
17271                stopped = true;
17272                // User can no longer run.
17273                mStartedUsers.remove(userId);
17274                mUserLru.remove(Integer.valueOf(userId));
17275                updateStartedUserArrayLocked();
17276
17277                // Clean up all state and processes associated with the user.
17278                // Kill all the processes for the user.
17279                forceStopUserLocked(userId, "finish user");
17280            }
17281        }
17282
17283        for (int i=0; i<callbacks.size(); i++) {
17284            try {
17285                if (stopped) callbacks.get(i).userStopped(userId);
17286                else callbacks.get(i).userStopAborted(userId);
17287            } catch (RemoteException e) {
17288            }
17289        }
17290
17291        if (stopped) {
17292            mSystemServiceManager.cleanupUser(userId);
17293            synchronized (this) {
17294                mStackSupervisor.removeUserLocked(userId);
17295            }
17296        }
17297    }
17298
17299    @Override
17300    public UserInfo getCurrentUser() {
17301        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17302                != PackageManager.PERMISSION_GRANTED) && (
17303                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17304                != PackageManager.PERMISSION_GRANTED)) {
17305            String msg = "Permission Denial: getCurrentUser() from pid="
17306                    + Binder.getCallingPid()
17307                    + ", uid=" + Binder.getCallingUid()
17308                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17309            Slog.w(TAG, msg);
17310            throw new SecurityException(msg);
17311        }
17312        synchronized (this) {
17313            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17314        }
17315    }
17316
17317    int getCurrentUserIdLocked() {
17318        return mCurrentUserId;
17319    }
17320
17321    @Override
17322    public boolean isUserRunning(int userId, boolean orStopped) {
17323        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17324                != PackageManager.PERMISSION_GRANTED) {
17325            String msg = "Permission Denial: isUserRunning() from pid="
17326                    + Binder.getCallingPid()
17327                    + ", uid=" + Binder.getCallingUid()
17328                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17329            Slog.w(TAG, msg);
17330            throw new SecurityException(msg);
17331        }
17332        synchronized (this) {
17333            return isUserRunningLocked(userId, orStopped);
17334        }
17335    }
17336
17337    boolean isUserRunningLocked(int userId, boolean orStopped) {
17338        UserStartedState state = mStartedUsers.get(userId);
17339        if (state == null) {
17340            return false;
17341        }
17342        if (orStopped) {
17343            return true;
17344        }
17345        return state.mState != UserStartedState.STATE_STOPPING
17346                && state.mState != UserStartedState.STATE_SHUTDOWN;
17347    }
17348
17349    @Override
17350    public int[] getRunningUserIds() {
17351        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17352                != PackageManager.PERMISSION_GRANTED) {
17353            String msg = "Permission Denial: isUserRunning() from pid="
17354                    + Binder.getCallingPid()
17355                    + ", uid=" + Binder.getCallingUid()
17356                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17357            Slog.w(TAG, msg);
17358            throw new SecurityException(msg);
17359        }
17360        synchronized (this) {
17361            return mStartedUserArray;
17362        }
17363    }
17364
17365    private void updateStartedUserArrayLocked() {
17366        int num = 0;
17367        for (int i=0; i<mStartedUsers.size();  i++) {
17368            UserStartedState uss = mStartedUsers.valueAt(i);
17369            // This list does not include stopping users.
17370            if (uss.mState != UserStartedState.STATE_STOPPING
17371                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17372                num++;
17373            }
17374        }
17375        mStartedUserArray = new int[num];
17376        num = 0;
17377        for (int i=0; i<mStartedUsers.size();  i++) {
17378            UserStartedState uss = mStartedUsers.valueAt(i);
17379            if (uss.mState != UserStartedState.STATE_STOPPING
17380                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17381                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17382                num++;
17383            }
17384        }
17385    }
17386
17387    @Override
17388    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17389        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17390                != PackageManager.PERMISSION_GRANTED) {
17391            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17392                    + Binder.getCallingPid()
17393                    + ", uid=" + Binder.getCallingUid()
17394                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17395            Slog.w(TAG, msg);
17396            throw new SecurityException(msg);
17397        }
17398
17399        mUserSwitchObservers.register(observer);
17400    }
17401
17402    @Override
17403    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17404        mUserSwitchObservers.unregister(observer);
17405    }
17406
17407    private boolean userExists(int userId) {
17408        if (userId == 0) {
17409            return true;
17410        }
17411        UserManagerService ums = getUserManagerLocked();
17412        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17413    }
17414
17415    int[] getUsersLocked() {
17416        UserManagerService ums = getUserManagerLocked();
17417        return ums != null ? ums.getUserIds() : new int[] { 0 };
17418    }
17419
17420    UserManagerService getUserManagerLocked() {
17421        if (mUserManager == null) {
17422            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17423            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17424        }
17425        return mUserManager;
17426    }
17427
17428    private int applyUserId(int uid, int userId) {
17429        return UserHandle.getUid(userId, uid);
17430    }
17431
17432    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17433        if (info == null) return null;
17434        ApplicationInfo newInfo = new ApplicationInfo(info);
17435        newInfo.uid = applyUserId(info.uid, userId);
17436        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17437                + info.packageName;
17438        return newInfo;
17439    }
17440
17441    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17442        if (aInfo == null
17443                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17444            return aInfo;
17445        }
17446
17447        ActivityInfo info = new ActivityInfo(aInfo);
17448        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17449        return info;
17450    }
17451
17452    private final class LocalService extends ActivityManagerInternal {
17453        @Override
17454        public void goingToSleep() {
17455            ActivityManagerService.this.goingToSleep();
17456        }
17457
17458        @Override
17459        public void wakingUp() {
17460            ActivityManagerService.this.wakingUp();
17461        }
17462    }
17463
17464    /**
17465     * An implementation of IAppTask, that allows an app to manage its own tasks via
17466     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17467     * only the process that calls getAppTasks() can call the AppTask methods.
17468     */
17469    class AppTaskImpl extends IAppTask.Stub {
17470        private int mTaskId;
17471        private int mCallingUid;
17472
17473        public AppTaskImpl(int taskId, int callingUid) {
17474            mTaskId = taskId;
17475            mCallingUid = callingUid;
17476        }
17477
17478        @Override
17479        public void finishAndRemoveTask() {
17480            // Ensure that we are called from the same process that created this AppTask
17481            if (mCallingUid != Binder.getCallingUid()) {
17482                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17483                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17484                return;
17485            }
17486
17487            synchronized (ActivityManagerService.this) {
17488                long origId = Binder.clearCallingIdentity();
17489                try {
17490                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17491                    if (tr != null) {
17492                        // Only kill the process if we are not a new document
17493                        int flags = tr.getBaseIntent().getFlags();
17494                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17495                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17496                        removeTaskByIdLocked(mTaskId,
17497                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17498                    }
17499                } finally {
17500                    Binder.restoreCallingIdentity(origId);
17501                }
17502            }
17503        }
17504
17505        @Override
17506        public ActivityManager.RecentTaskInfo getTaskInfo() {
17507            // Ensure that we are called from the same process that created this AppTask
17508            if (mCallingUid != Binder.getCallingUid()) {
17509                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17510                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17511                return null;
17512            }
17513
17514            synchronized (ActivityManagerService.this) {
17515                long origId = Binder.clearCallingIdentity();
17516                try {
17517                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17518                    if (tr != null) {
17519                        return createRecentTaskInfoFromTaskRecord(tr);
17520                    }
17521                } finally {
17522                    Binder.restoreCallingIdentity(origId);
17523                }
17524                return null;
17525            }
17526        }
17527    }
17528}
17529