ActivityManagerService.java revision a4e946bb6f4481d44463c620332d0666e3b8ad20
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        rti.lastActiveTime = tr.lastActiveTime;
7240        return rti;
7241    }
7242
7243    @Override
7244    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7245            int flags, int userId) {
7246        final int callingUid = Binder.getCallingUid();
7247        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7248                false, true, "getRecentTasks", null);
7249
7250        synchronized (this) {
7251            final boolean allowed = checkCallingPermission(
7252                    android.Manifest.permission.GET_TASKS)
7253                    == PackageManager.PERMISSION_GRANTED;
7254            if (!allowed) {
7255                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7256                        + " does not hold GET_TASKS; limiting output");
7257            }
7258            final boolean detailed = checkCallingPermission(
7259                    android.Manifest.permission.GET_DETAILED_TASKS)
7260                    == PackageManager.PERMISSION_GRANTED;
7261
7262            IPackageManager pm = AppGlobals.getPackageManager();
7263
7264            final int N = mRecentTasks.size();
7265            ArrayList<ActivityManager.RecentTaskInfo> res
7266                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7267                            maxNum < N ? maxNum : N);
7268
7269            final Set<Integer> includedUsers;
7270            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7271                includedUsers = getProfileIdsLocked(userId);
7272            } else {
7273                includedUsers = new HashSet<Integer>();
7274            }
7275            includedUsers.add(Integer.valueOf(userId));
7276            for (int i=0; i<N && maxNum > 0; i++) {
7277                TaskRecord tr = mRecentTasks.get(i);
7278                // Only add calling user or related users recent tasks
7279                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7280
7281                // Return the entry if desired by the caller.  We always return
7282                // the first entry, because callers always expect this to be the
7283                // foreground app.  We may filter others if the caller has
7284                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7285                // we should exclude the entry.
7286
7287                if (i == 0
7288                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7289                        || (tr.intent == null)
7290                        || ((tr.intent.getFlags()
7291                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7292                    if (!allowed) {
7293                        // If the caller doesn't have the GET_TASKS permission, then only
7294                        // allow them to see a small subset of tasks -- their own and home.
7295                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7296                            continue;
7297                        }
7298                    }
7299                    if (tr.intent != null &&
7300                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7301                            != 0 && tr.getTopActivity() == null) {
7302                        // Don't include auto remove tasks that are finished or finishing.
7303                        continue;
7304                    }
7305
7306                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7307                    if (!detailed) {
7308                        rti.baseIntent.replaceExtras((Bundle)null);
7309                    }
7310
7311                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7312                        // Check whether this activity is currently available.
7313                        try {
7314                            if (rti.origActivity != null) {
7315                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7316                                        == null) {
7317                                    continue;
7318                                }
7319                            } else if (rti.baseIntent != null) {
7320                                if (pm.queryIntentActivities(rti.baseIntent,
7321                                        null, 0, userId) == null) {
7322                                    continue;
7323                                }
7324                            }
7325                        } catch (RemoteException e) {
7326                            // Will never happen.
7327                        }
7328                    }
7329
7330                    res.add(rti);
7331                    maxNum--;
7332                }
7333            }
7334            return res;
7335        }
7336    }
7337
7338    private TaskRecord recentTaskForIdLocked(int id) {
7339        final int N = mRecentTasks.size();
7340            for (int i=0; i<N; i++) {
7341                TaskRecord tr = mRecentTasks.get(i);
7342                if (tr.taskId == id) {
7343                    return tr;
7344                }
7345            }
7346            return null;
7347    }
7348
7349    @Override
7350    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7351        synchronized (this) {
7352            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7353                    "getTaskThumbnails()");
7354            TaskRecord tr = recentTaskForIdLocked(id);
7355            if (tr != null) {
7356                return tr.getTaskThumbnailsLocked();
7357            }
7358        }
7359        return null;
7360    }
7361
7362    @Override
7363    public Bitmap getTaskTopThumbnail(int id) {
7364        synchronized (this) {
7365            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7366                    "getTaskTopThumbnail()");
7367            TaskRecord tr = recentTaskForIdLocked(id);
7368            if (tr != null) {
7369                return tr.getTaskTopThumbnailLocked();
7370            }
7371        }
7372        return null;
7373    }
7374
7375    @Override
7376    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7377        synchronized (this) {
7378            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7379            if (r != null) {
7380                r.taskDescription = td;
7381                r.task.updateTaskDescription();
7382            }
7383        }
7384    }
7385
7386    @Override
7387    public boolean removeSubTask(int taskId, int subTaskIndex) {
7388        synchronized (this) {
7389            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7390                    "removeSubTask()");
7391            long ident = Binder.clearCallingIdentity();
7392            try {
7393                TaskRecord tr = recentTaskForIdLocked(taskId);
7394                if (tr != null) {
7395                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7396                }
7397                return false;
7398            } finally {
7399                Binder.restoreCallingIdentity(ident);
7400            }
7401        }
7402    }
7403
7404    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7405        if (!pr.killedByAm) {
7406            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7407            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7408                    pr.processName, pr.setAdj, reason);
7409            pr.killedByAm = true;
7410            Process.killProcessQuiet(pr.pid);
7411        }
7412    }
7413
7414    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7415        tr.disposeThumbnail();
7416        mRecentTasks.remove(tr);
7417        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7418        Intent baseIntent = new Intent(
7419                tr.intent != null ? tr.intent : tr.affinityIntent);
7420        ComponentName component = baseIntent.getComponent();
7421        if (component == null) {
7422            Slog.w(TAG, "Now component for base intent of task: " + tr);
7423            return;
7424        }
7425
7426        // Find any running services associated with this app.
7427        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7428
7429        if (killProcesses) {
7430            // Find any running processes associated with this app.
7431            final String pkg = component.getPackageName();
7432            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7433            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7434            for (int i=0; i<pmap.size(); i++) {
7435                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7436                for (int j=0; j<uids.size(); j++) {
7437                    ProcessRecord proc = uids.valueAt(j);
7438                    if (proc.userId != tr.userId) {
7439                        continue;
7440                    }
7441                    if (!proc.pkgList.containsKey(pkg)) {
7442                        continue;
7443                    }
7444                    procs.add(proc);
7445                }
7446            }
7447
7448            // Kill the running processes.
7449            for (int i=0; i<procs.size(); i++) {
7450                ProcessRecord pr = procs.get(i);
7451                if (pr == mHomeProcess) {
7452                    // Don't kill the home process along with tasks from the same package.
7453                    continue;
7454                }
7455                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7456                    killUnneededProcessLocked(pr, "remove task");
7457                } else {
7458                    pr.waitingToKill = "remove task";
7459                }
7460            }
7461        }
7462    }
7463
7464    /**
7465     * Removes the task with the specified task id.
7466     *
7467     * @param taskId Identifier of the task to be removed.
7468     * @param flags Additional operational flags.  May be 0 or
7469     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7470     * @return Returns true if the given task was found and removed.
7471     */
7472    private boolean removeTaskByIdLocked(int taskId, int flags) {
7473        TaskRecord tr = recentTaskForIdLocked(taskId);
7474        if (tr != null) {
7475            tr.removeTaskActivitiesLocked(-1, false);
7476            cleanUpRemovedTaskLocked(tr, flags);
7477            if (tr.isPersistable) {
7478                notifyTaskPersisterLocked(tr, true);
7479            }
7480            return true;
7481        }
7482        return false;
7483    }
7484
7485    @Override
7486    public boolean removeTask(int taskId, int flags) {
7487        synchronized (this) {
7488            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7489                    "removeTask()");
7490            long ident = Binder.clearCallingIdentity();
7491            try {
7492                return removeTaskByIdLocked(taskId, flags);
7493            } finally {
7494                Binder.restoreCallingIdentity(ident);
7495            }
7496        }
7497    }
7498
7499    /**
7500     * TODO: Add mController hook
7501     */
7502    @Override
7503    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7504        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7505                "moveTaskToFront()");
7506
7507        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7508        synchronized(this) {
7509            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7510                    Binder.getCallingUid(), "Task to front")) {
7511                ActivityOptions.abort(options);
7512                return;
7513            }
7514            final long origId = Binder.clearCallingIdentity();
7515            try {
7516                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7517                if (task == null) {
7518                    return;
7519                }
7520                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7521                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7522                    return;
7523                }
7524                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7525                if (prev != null && prev.isRecentsActivity()) {
7526                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7527                }
7528                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7529            } finally {
7530                Binder.restoreCallingIdentity(origId);
7531            }
7532            ActivityOptions.abort(options);
7533        }
7534    }
7535
7536    @Override
7537    public void moveTaskToBack(int taskId) {
7538        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7539                "moveTaskToBack()");
7540
7541        synchronized(this) {
7542            TaskRecord tr = recentTaskForIdLocked(taskId);
7543            if (tr != null) {
7544                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7545                ActivityStack stack = tr.stack;
7546                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7547                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7548                            Binder.getCallingUid(), "Task to back")) {
7549                        return;
7550                    }
7551                }
7552                final long origId = Binder.clearCallingIdentity();
7553                try {
7554                    stack.moveTaskToBackLocked(taskId, null);
7555                } finally {
7556                    Binder.restoreCallingIdentity(origId);
7557                }
7558            }
7559        }
7560    }
7561
7562    /**
7563     * Moves an activity, and all of the other activities within the same task, to the bottom
7564     * of the history stack.  The activity's order within the task is unchanged.
7565     *
7566     * @param token A reference to the activity we wish to move
7567     * @param nonRoot If false then this only works if the activity is the root
7568     *                of a task; if true it will work for any activity in a task.
7569     * @return Returns true if the move completed, false if not.
7570     */
7571    @Override
7572    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7573        enforceNotIsolatedCaller("moveActivityTaskToBack");
7574        synchronized(this) {
7575            final long origId = Binder.clearCallingIdentity();
7576            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7577            if (taskId >= 0) {
7578                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7579            }
7580            Binder.restoreCallingIdentity(origId);
7581        }
7582        return false;
7583    }
7584
7585    @Override
7586    public void moveTaskBackwards(int task) {
7587        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7588                "moveTaskBackwards()");
7589
7590        synchronized(this) {
7591            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7592                    Binder.getCallingUid(), "Task backwards")) {
7593                return;
7594            }
7595            final long origId = Binder.clearCallingIdentity();
7596            moveTaskBackwardsLocked(task);
7597            Binder.restoreCallingIdentity(origId);
7598        }
7599    }
7600
7601    private final void moveTaskBackwardsLocked(int task) {
7602        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7603    }
7604
7605    @Override
7606    public IBinder getHomeActivityToken() throws RemoteException {
7607        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7608                "getHomeActivityToken()");
7609        synchronized (this) {
7610            return mStackSupervisor.getHomeActivityToken();
7611        }
7612    }
7613
7614    @Override
7615    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7616            IActivityContainerCallback callback) throws RemoteException {
7617        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7618                "createActivityContainer()");
7619        synchronized (this) {
7620            if (parentActivityToken == null) {
7621                throw new IllegalArgumentException("parent token must not be null");
7622            }
7623            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7624            if (r == null) {
7625                return null;
7626            }
7627            if (callback == null) {
7628                throw new IllegalArgumentException("callback must not be null");
7629            }
7630            return mStackSupervisor.createActivityContainer(r, callback);
7631        }
7632    }
7633
7634    @Override
7635    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7636        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7637                "deleteActivityContainer()");
7638        synchronized (this) {
7639            mStackSupervisor.deleteActivityContainer(container);
7640        }
7641    }
7642
7643    @Override
7644    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7645            throws RemoteException {
7646        synchronized (this) {
7647            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7648            if (stack != null) {
7649                return stack.mActivityContainer;
7650            }
7651            return null;
7652        }
7653    }
7654
7655    @Override
7656    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7657        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7658                "moveTaskToStack()");
7659        if (stackId == HOME_STACK_ID) {
7660            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7661                    new RuntimeException("here").fillInStackTrace());
7662        }
7663        synchronized (this) {
7664            long ident = Binder.clearCallingIdentity();
7665            try {
7666                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7667                        + stackId + " toTop=" + toTop);
7668                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7669            } finally {
7670                Binder.restoreCallingIdentity(ident);
7671            }
7672        }
7673    }
7674
7675    @Override
7676    public void resizeStack(int stackBoxId, Rect bounds) {
7677        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7678                "resizeStackBox()");
7679        long ident = Binder.clearCallingIdentity();
7680        try {
7681            mWindowManager.resizeStack(stackBoxId, bounds);
7682        } finally {
7683            Binder.restoreCallingIdentity(ident);
7684        }
7685    }
7686
7687    @Override
7688    public List<StackInfo> getAllStackInfos() {
7689        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7690                "getAllStackInfos()");
7691        long ident = Binder.clearCallingIdentity();
7692        try {
7693            synchronized (this) {
7694                return mStackSupervisor.getAllStackInfosLocked();
7695            }
7696        } finally {
7697            Binder.restoreCallingIdentity(ident);
7698        }
7699    }
7700
7701    @Override
7702    public StackInfo getStackInfo(int stackId) {
7703        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7704                "getStackInfo()");
7705        long ident = Binder.clearCallingIdentity();
7706        try {
7707            synchronized (this) {
7708                return mStackSupervisor.getStackInfoLocked(stackId);
7709            }
7710        } finally {
7711            Binder.restoreCallingIdentity(ident);
7712        }
7713    }
7714
7715    @Override
7716    public boolean isInHomeStack(int taskId) {
7717        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7718                "getStackInfo()");
7719        long ident = Binder.clearCallingIdentity();
7720        try {
7721            synchronized (this) {
7722                TaskRecord tr = recentTaskForIdLocked(taskId);
7723                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7724            }
7725        } finally {
7726            Binder.restoreCallingIdentity(ident);
7727        }
7728    }
7729
7730    @Override
7731    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7732        synchronized(this) {
7733            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7734        }
7735    }
7736
7737    private boolean isLockTaskAuthorized(String pkg) {
7738        final DevicePolicyManager dpm = (DevicePolicyManager)
7739                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7740        try {
7741            int uid = mContext.getPackageManager().getPackageUid(pkg,
7742                    Binder.getCallingUserHandle().getIdentifier());
7743            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7744        } catch (NameNotFoundException e) {
7745            return false;
7746        }
7747    }
7748
7749    void startLockTaskMode(TaskRecord task) {
7750        final String pkg;
7751        synchronized (this) {
7752            pkg = task.intent.getComponent().getPackageName();
7753        }
7754        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7755        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7756            final TaskRecord taskRecord = task;
7757            mHandler.post(new Runnable() {
7758                @Override
7759                public void run() {
7760                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7761                }
7762            });
7763            return;
7764        }
7765        long ident = Binder.clearCallingIdentity();
7766        try {
7767            synchronized (this) {
7768                // Since we lost lock on task, make sure it is still there.
7769                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7770                if (task != null) {
7771                    if (!isSystemInitiated
7772                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7773                        throw new IllegalArgumentException("Invalid task, not in foreground");
7774                    }
7775                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7776                }
7777            }
7778        } finally {
7779            Binder.restoreCallingIdentity(ident);
7780        }
7781    }
7782
7783    @Override
7784    public void startLockTaskMode(int taskId) {
7785        final TaskRecord task;
7786        long ident = Binder.clearCallingIdentity();
7787        try {
7788            synchronized (this) {
7789                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7790            }
7791        } finally {
7792            Binder.restoreCallingIdentity(ident);
7793        }
7794        if (task != null) {
7795            startLockTaskMode(task);
7796        }
7797    }
7798
7799    @Override
7800    public void startLockTaskMode(IBinder token) {
7801        final TaskRecord task;
7802        long ident = Binder.clearCallingIdentity();
7803        try {
7804            synchronized (this) {
7805                final ActivityRecord r = ActivityRecord.forToken(token);
7806                if (r == null) {
7807                    return;
7808                }
7809                task = r.task;
7810            }
7811        } finally {
7812            Binder.restoreCallingIdentity(ident);
7813        }
7814        if (task != null) {
7815            startLockTaskMode(task);
7816        }
7817    }
7818
7819    @Override
7820    public void startLockTaskModeOnCurrent() throws RemoteException {
7821        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7822        ActivityRecord r = null;
7823        synchronized (this) {
7824            r = mStackSupervisor.topRunningActivityLocked();
7825        }
7826        startLockTaskMode(r.task);
7827    }
7828
7829    @Override
7830    public void stopLockTaskMode() {
7831        // Verify that the user matches the package of the intent for the TaskRecord
7832        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7833        // and stopLockTaskMode.
7834        final int callingUid = Binder.getCallingUid();
7835        if (callingUid != Process.SYSTEM_UID) {
7836            try {
7837                String pkg =
7838                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7839                int uid = mContext.getPackageManager().getPackageUid(pkg,
7840                        Binder.getCallingUserHandle().getIdentifier());
7841                if (uid != callingUid) {
7842                    throw new SecurityException("Invalid uid, expected " + uid);
7843                }
7844            } catch (NameNotFoundException e) {
7845                Log.d(TAG, "stopLockTaskMode " + e);
7846                return;
7847            }
7848        }
7849        long ident = Binder.clearCallingIdentity();
7850        try {
7851            Log.d(TAG, "stopLockTaskMode");
7852            // Stop lock task
7853            synchronized (this) {
7854                mStackSupervisor.setLockTaskModeLocked(null, false);
7855            }
7856        } finally {
7857            Binder.restoreCallingIdentity(ident);
7858        }
7859    }
7860
7861    @Override
7862    public void stopLockTaskModeOnCurrent() throws RemoteException {
7863        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7864        long ident = Binder.clearCallingIdentity();
7865        try {
7866            stopLockTaskMode();
7867        } finally {
7868            Binder.restoreCallingIdentity(ident);
7869        }
7870    }
7871
7872    @Override
7873    public boolean isInLockTaskMode() {
7874        synchronized (this) {
7875            return mStackSupervisor.isInLockTaskMode();
7876        }
7877    }
7878
7879    // =========================================================
7880    // CONTENT PROVIDERS
7881    // =========================================================
7882
7883    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7884        List<ProviderInfo> providers = null;
7885        try {
7886            providers = AppGlobals.getPackageManager().
7887                queryContentProviders(app.processName, app.uid,
7888                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7889        } catch (RemoteException ex) {
7890        }
7891        if (DEBUG_MU)
7892            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7893        int userId = app.userId;
7894        if (providers != null) {
7895            int N = providers.size();
7896            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7897            for (int i=0; i<N; i++) {
7898                ProviderInfo cpi =
7899                    (ProviderInfo)providers.get(i);
7900                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7901                        cpi.name, cpi.flags);
7902                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7903                    // This is a singleton provider, but a user besides the
7904                    // default user is asking to initialize a process it runs
7905                    // in...  well, no, it doesn't actually run in this process,
7906                    // it runs in the process of the default user.  Get rid of it.
7907                    providers.remove(i);
7908                    N--;
7909                    i--;
7910                    continue;
7911                }
7912
7913                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7914                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7915                if (cpr == null) {
7916                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7917                    mProviderMap.putProviderByClass(comp, cpr);
7918                }
7919                if (DEBUG_MU)
7920                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7921                app.pubProviders.put(cpi.name, cpr);
7922                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7923                    // Don't add this if it is a platform component that is marked
7924                    // to run in multiple processes, because this is actually
7925                    // part of the framework so doesn't make sense to track as a
7926                    // separate apk in the process.
7927                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7928                            mProcessStats);
7929                }
7930                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7931            }
7932        }
7933        return providers;
7934    }
7935
7936    /**
7937     * Check if {@link ProcessRecord} has a possible chance at accessing the
7938     * given {@link ProviderInfo}. Final permission checking is always done
7939     * in {@link ContentProvider}.
7940     */
7941    private final String checkContentProviderPermissionLocked(
7942            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7943        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7944        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7945        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7946        // Looking for cross-user grants before to enforce the typical cross-users permissions
7947        if (userId != UserHandle.getUserId(callingUid)) {
7948            if (perms != null) {
7949                for (GrantUri grantUri : perms.keySet()) {
7950                    if (grantUri.sourceUserId == userId) {
7951                        String authority = grantUri.uri.getAuthority();
7952                        if (authority.equals(cpi.authority)) {
7953                            return null;
7954                        }
7955                    }
7956                }
7957            }
7958        }
7959        if (checkUser) {
7960            userId = handleIncomingUser(callingPid, callingUid, userId,
7961                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7962        }
7963        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7964                cpi.applicationInfo.uid, cpi.exported)
7965                == PackageManager.PERMISSION_GRANTED) {
7966            return null;
7967        }
7968        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7969                cpi.applicationInfo.uid, cpi.exported)
7970                == PackageManager.PERMISSION_GRANTED) {
7971            return null;
7972        }
7973
7974        PathPermission[] pps = cpi.pathPermissions;
7975        if (pps != null) {
7976            int i = pps.length;
7977            while (i > 0) {
7978                i--;
7979                PathPermission pp = pps[i];
7980                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7981                        cpi.applicationInfo.uid, cpi.exported)
7982                        == PackageManager.PERMISSION_GRANTED) {
7983                    return null;
7984                }
7985                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7986                        cpi.applicationInfo.uid, cpi.exported)
7987                        == PackageManager.PERMISSION_GRANTED) {
7988                    return null;
7989                }
7990            }
7991        }
7992
7993        if (perms != null) {
7994            for (GrantUri grantUri : perms.keySet()) {
7995                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7996                    return null;
7997                }
7998            }
7999        }
8000
8001        String msg;
8002        if (!cpi.exported) {
8003            msg = "Permission Denial: opening provider " + cpi.name
8004                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8005                    + ", uid=" + callingUid + ") that is not exported from uid "
8006                    + cpi.applicationInfo.uid;
8007        } else {
8008            msg = "Permission Denial: opening provider " + cpi.name
8009                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8010                    + ", uid=" + callingUid + ") requires "
8011                    + cpi.readPermission + " or " + cpi.writePermission;
8012        }
8013        Slog.w(TAG, msg);
8014        return msg;
8015    }
8016
8017    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8018            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8019        if (r != null) {
8020            for (int i=0; i<r.conProviders.size(); i++) {
8021                ContentProviderConnection conn = r.conProviders.get(i);
8022                if (conn.provider == cpr) {
8023                    if (DEBUG_PROVIDER) Slog.v(TAG,
8024                            "Adding provider requested by "
8025                            + r.processName + " from process "
8026                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8027                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8028                    if (stable) {
8029                        conn.stableCount++;
8030                        conn.numStableIncs++;
8031                    } else {
8032                        conn.unstableCount++;
8033                        conn.numUnstableIncs++;
8034                    }
8035                    return conn;
8036                }
8037            }
8038            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8039            if (stable) {
8040                conn.stableCount = 1;
8041                conn.numStableIncs = 1;
8042            } else {
8043                conn.unstableCount = 1;
8044                conn.numUnstableIncs = 1;
8045            }
8046            cpr.connections.add(conn);
8047            r.conProviders.add(conn);
8048            return conn;
8049        }
8050        cpr.addExternalProcessHandleLocked(externalProcessToken);
8051        return null;
8052    }
8053
8054    boolean decProviderCountLocked(ContentProviderConnection conn,
8055            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8056        if (conn != null) {
8057            cpr = conn.provider;
8058            if (DEBUG_PROVIDER) Slog.v(TAG,
8059                    "Removing provider requested by "
8060                    + conn.client.processName + " from process "
8061                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8062                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8063            if (stable) {
8064                conn.stableCount--;
8065            } else {
8066                conn.unstableCount--;
8067            }
8068            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8069                cpr.connections.remove(conn);
8070                conn.client.conProviders.remove(conn);
8071                return true;
8072            }
8073            return false;
8074        }
8075        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8076        return false;
8077    }
8078
8079    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8080            String name, IBinder token, boolean stable, int userId) {
8081        ContentProviderRecord cpr;
8082        ContentProviderConnection conn = null;
8083        ProviderInfo cpi = null;
8084
8085        synchronized(this) {
8086            ProcessRecord r = null;
8087            if (caller != null) {
8088                r = getRecordForAppLocked(caller);
8089                if (r == null) {
8090                    throw new SecurityException(
8091                            "Unable to find app for caller " + caller
8092                          + " (pid=" + Binder.getCallingPid()
8093                          + ") when getting content provider " + name);
8094                }
8095            }
8096
8097            boolean checkCrossUser = true;
8098
8099            // First check if this content provider has been published...
8100            cpr = mProviderMap.getProviderByName(name, userId);
8101            // If that didn't work, check if it exists for user 0 and then
8102            // verify that it's a singleton provider before using it.
8103            if (cpr == null && userId != UserHandle.USER_OWNER) {
8104                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8105                if (cpr != null) {
8106                    cpi = cpr.info;
8107                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8108                            cpi.name, cpi.flags)
8109                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8110                        userId = UserHandle.USER_OWNER;
8111                        checkCrossUser = false;
8112                    } else {
8113                        cpr = null;
8114                        cpi = null;
8115                    }
8116                }
8117            }
8118
8119            boolean providerRunning = cpr != null;
8120            if (providerRunning) {
8121                cpi = cpr.info;
8122                String msg;
8123                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8124                        != null) {
8125                    throw new SecurityException(msg);
8126                }
8127
8128                if (r != null && cpr.canRunHere(r)) {
8129                    // This provider has been published or is in the process
8130                    // of being published...  but it is also allowed to run
8131                    // in the caller's process, so don't make a connection
8132                    // and just let the caller instantiate its own instance.
8133                    ContentProviderHolder holder = cpr.newHolder(null);
8134                    // don't give caller the provider object, it needs
8135                    // to make its own.
8136                    holder.provider = null;
8137                    return holder;
8138                }
8139
8140                final long origId = Binder.clearCallingIdentity();
8141
8142                // In this case the provider instance already exists, so we can
8143                // return it right away.
8144                conn = incProviderCountLocked(r, cpr, token, stable);
8145                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8146                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8147                        // If this is a perceptible app accessing the provider,
8148                        // make sure to count it as being accessed and thus
8149                        // back up on the LRU list.  This is good because
8150                        // content providers are often expensive to start.
8151                        updateLruProcessLocked(cpr.proc, false, null);
8152                    }
8153                }
8154
8155                if (cpr.proc != null) {
8156                    if (false) {
8157                        if (cpr.name.flattenToShortString().equals(
8158                                "com.android.providers.calendar/.CalendarProvider2")) {
8159                            Slog.v(TAG, "****************** KILLING "
8160                                + cpr.name.flattenToShortString());
8161                            Process.killProcess(cpr.proc.pid);
8162                        }
8163                    }
8164                    boolean success = updateOomAdjLocked(cpr.proc);
8165                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8166                    // NOTE: there is still a race here where a signal could be
8167                    // pending on the process even though we managed to update its
8168                    // adj level.  Not sure what to do about this, but at least
8169                    // the race is now smaller.
8170                    if (!success) {
8171                        // Uh oh...  it looks like the provider's process
8172                        // has been killed on us.  We need to wait for a new
8173                        // process to be started, and make sure its death
8174                        // doesn't kill our process.
8175                        Slog.i(TAG,
8176                                "Existing provider " + cpr.name.flattenToShortString()
8177                                + " is crashing; detaching " + r);
8178                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8179                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8180                        if (!lastRef) {
8181                            // This wasn't the last ref our process had on
8182                            // the provider...  we have now been killed, bail.
8183                            return null;
8184                        }
8185                        providerRunning = false;
8186                        conn = null;
8187                    }
8188                }
8189
8190                Binder.restoreCallingIdentity(origId);
8191            }
8192
8193            boolean singleton;
8194            if (!providerRunning) {
8195                try {
8196                    cpi = AppGlobals.getPackageManager().
8197                        resolveContentProvider(name,
8198                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8199                } catch (RemoteException ex) {
8200                }
8201                if (cpi == null) {
8202                    return null;
8203                }
8204                // If the provider is a singleton AND
8205                // (it's a call within the same user || the provider is a
8206                // privileged app)
8207                // Then allow connecting to the singleton provider
8208                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8209                        cpi.name, cpi.flags)
8210                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8211                if (singleton) {
8212                    userId = UserHandle.USER_OWNER;
8213                }
8214                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8215
8216                String msg;
8217                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8218                        != null) {
8219                    throw new SecurityException(msg);
8220                }
8221
8222                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8223                        && !cpi.processName.equals("system")) {
8224                    // If this content provider does not run in the system
8225                    // process, and the system is not yet ready to run other
8226                    // processes, then fail fast instead of hanging.
8227                    throw new IllegalArgumentException(
8228                            "Attempt to launch content provider before system ready");
8229                }
8230
8231                // Make sure that the user who owns this provider is started.  If not,
8232                // we don't want to allow it to run.
8233                if (mStartedUsers.get(userId) == null) {
8234                    Slog.w(TAG, "Unable to launch app "
8235                            + cpi.applicationInfo.packageName + "/"
8236                            + cpi.applicationInfo.uid + " for provider "
8237                            + name + ": user " + userId + " is stopped");
8238                    return null;
8239                }
8240
8241                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8242                cpr = mProviderMap.getProviderByClass(comp, userId);
8243                final boolean firstClass = cpr == null;
8244                if (firstClass) {
8245                    try {
8246                        ApplicationInfo ai =
8247                            AppGlobals.getPackageManager().
8248                                getApplicationInfo(
8249                                        cpi.applicationInfo.packageName,
8250                                        STOCK_PM_FLAGS, userId);
8251                        if (ai == null) {
8252                            Slog.w(TAG, "No package info for content provider "
8253                                    + cpi.name);
8254                            return null;
8255                        }
8256                        ai = getAppInfoForUser(ai, userId);
8257                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8258                    } catch (RemoteException ex) {
8259                        // pm is in same process, this will never happen.
8260                    }
8261                }
8262
8263                if (r != null && cpr.canRunHere(r)) {
8264                    // If this is a multiprocess provider, then just return its
8265                    // info and allow the caller to instantiate it.  Only do
8266                    // this if the provider is the same user as the caller's
8267                    // process, or can run as root (so can be in any process).
8268                    return cpr.newHolder(null);
8269                }
8270
8271                if (DEBUG_PROVIDER) {
8272                    RuntimeException e = new RuntimeException("here");
8273                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8274                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8275                }
8276
8277                // This is single process, and our app is now connecting to it.
8278                // See if we are already in the process of launching this
8279                // provider.
8280                final int N = mLaunchingProviders.size();
8281                int i;
8282                for (i=0; i<N; i++) {
8283                    if (mLaunchingProviders.get(i) == cpr) {
8284                        break;
8285                    }
8286                }
8287
8288                // If the provider is not already being launched, then get it
8289                // started.
8290                if (i >= N) {
8291                    final long origId = Binder.clearCallingIdentity();
8292
8293                    try {
8294                        // Content provider is now in use, its package can't be stopped.
8295                        try {
8296                            AppGlobals.getPackageManager().setPackageStoppedState(
8297                                    cpr.appInfo.packageName, false, userId);
8298                        } catch (RemoteException e) {
8299                        } catch (IllegalArgumentException e) {
8300                            Slog.w(TAG, "Failed trying to unstop package "
8301                                    + cpr.appInfo.packageName + ": " + e);
8302                        }
8303
8304                        // Use existing process if already started
8305                        ProcessRecord proc = getProcessRecordLocked(
8306                                cpi.processName, cpr.appInfo.uid, false);
8307                        if (proc != null && proc.thread != null) {
8308                            if (DEBUG_PROVIDER) {
8309                                Slog.d(TAG, "Installing in existing process " + proc);
8310                            }
8311                            proc.pubProviders.put(cpi.name, cpr);
8312                            try {
8313                                proc.thread.scheduleInstallProvider(cpi);
8314                            } catch (RemoteException e) {
8315                            }
8316                        } else {
8317                            proc = startProcessLocked(cpi.processName,
8318                                    cpr.appInfo, false, 0, "content provider",
8319                                    new ComponentName(cpi.applicationInfo.packageName,
8320                                            cpi.name), false, false, false);
8321                            if (proc == null) {
8322                                Slog.w(TAG, "Unable to launch app "
8323                                        + cpi.applicationInfo.packageName + "/"
8324                                        + cpi.applicationInfo.uid + " for provider "
8325                                        + name + ": process is bad");
8326                                return null;
8327                            }
8328                        }
8329                        cpr.launchingApp = proc;
8330                        mLaunchingProviders.add(cpr);
8331                    } finally {
8332                        Binder.restoreCallingIdentity(origId);
8333                    }
8334                }
8335
8336                // Make sure the provider is published (the same provider class
8337                // may be published under multiple names).
8338                if (firstClass) {
8339                    mProviderMap.putProviderByClass(comp, cpr);
8340                }
8341
8342                mProviderMap.putProviderByName(name, cpr);
8343                conn = incProviderCountLocked(r, cpr, token, stable);
8344                if (conn != null) {
8345                    conn.waiting = true;
8346                }
8347            }
8348        }
8349
8350        // Wait for the provider to be published...
8351        synchronized (cpr) {
8352            while (cpr.provider == null) {
8353                if (cpr.launchingApp == null) {
8354                    Slog.w(TAG, "Unable to launch app "
8355                            + cpi.applicationInfo.packageName + "/"
8356                            + cpi.applicationInfo.uid + " for provider "
8357                            + name + ": launching app became null");
8358                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8359                            UserHandle.getUserId(cpi.applicationInfo.uid),
8360                            cpi.applicationInfo.packageName,
8361                            cpi.applicationInfo.uid, name);
8362                    return null;
8363                }
8364                try {
8365                    if (DEBUG_MU) {
8366                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8367                                + cpr.launchingApp);
8368                    }
8369                    if (conn != null) {
8370                        conn.waiting = true;
8371                    }
8372                    cpr.wait();
8373                } catch (InterruptedException ex) {
8374                } finally {
8375                    if (conn != null) {
8376                        conn.waiting = false;
8377                    }
8378                }
8379            }
8380        }
8381        return cpr != null ? cpr.newHolder(conn) : null;
8382    }
8383
8384    @Override
8385    public final ContentProviderHolder getContentProvider(
8386            IApplicationThread caller, String name, int userId, boolean stable) {
8387        enforceNotIsolatedCaller("getContentProvider");
8388        if (caller == null) {
8389            String msg = "null IApplicationThread when getting content provider "
8390                    + name;
8391            Slog.w(TAG, msg);
8392            throw new SecurityException(msg);
8393        }
8394        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8395        // with cross-user grant.
8396        return getContentProviderImpl(caller, name, null, stable, userId);
8397    }
8398
8399    public ContentProviderHolder getContentProviderExternal(
8400            String name, int userId, IBinder token) {
8401        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8402            "Do not have permission in call getContentProviderExternal()");
8403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8404                false, true, "getContentProvider", null);
8405        return getContentProviderExternalUnchecked(name, token, userId);
8406    }
8407
8408    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8409            IBinder token, int userId) {
8410        return getContentProviderImpl(null, name, token, true, userId);
8411    }
8412
8413    /**
8414     * Drop a content provider from a ProcessRecord's bookkeeping
8415     */
8416    public void removeContentProvider(IBinder connection, boolean stable) {
8417        enforceNotIsolatedCaller("removeContentProvider");
8418        long ident = Binder.clearCallingIdentity();
8419        try {
8420            synchronized (this) {
8421                ContentProviderConnection conn;
8422                try {
8423                    conn = (ContentProviderConnection)connection;
8424                } catch (ClassCastException e) {
8425                    String msg ="removeContentProvider: " + connection
8426                            + " not a ContentProviderConnection";
8427                    Slog.w(TAG, msg);
8428                    throw new IllegalArgumentException(msg);
8429                }
8430                if (conn == null) {
8431                    throw new NullPointerException("connection is null");
8432                }
8433                if (decProviderCountLocked(conn, null, null, stable)) {
8434                    updateOomAdjLocked();
8435                }
8436            }
8437        } finally {
8438            Binder.restoreCallingIdentity(ident);
8439        }
8440    }
8441
8442    public void removeContentProviderExternal(String name, IBinder token) {
8443        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8444            "Do not have permission in call removeContentProviderExternal()");
8445        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8446    }
8447
8448    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8449        synchronized (this) {
8450            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8451            if(cpr == null) {
8452                //remove from mProvidersByClass
8453                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8454                return;
8455            }
8456
8457            //update content provider record entry info
8458            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8459            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8460            if (localCpr.hasExternalProcessHandles()) {
8461                if (localCpr.removeExternalProcessHandleLocked(token)) {
8462                    updateOomAdjLocked();
8463                } else {
8464                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8465                            + " with no external reference for token: "
8466                            + token + ".");
8467                }
8468            } else {
8469                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8470                        + " with no external references.");
8471            }
8472        }
8473    }
8474
8475    public final void publishContentProviders(IApplicationThread caller,
8476            List<ContentProviderHolder> providers) {
8477        if (providers == null) {
8478            return;
8479        }
8480
8481        enforceNotIsolatedCaller("publishContentProviders");
8482        synchronized (this) {
8483            final ProcessRecord r = getRecordForAppLocked(caller);
8484            if (DEBUG_MU)
8485                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8486            if (r == null) {
8487                throw new SecurityException(
8488                        "Unable to find app for caller " + caller
8489                      + " (pid=" + Binder.getCallingPid()
8490                      + ") when publishing content providers");
8491            }
8492
8493            final long origId = Binder.clearCallingIdentity();
8494
8495            final int N = providers.size();
8496            for (int i=0; i<N; i++) {
8497                ContentProviderHolder src = providers.get(i);
8498                if (src == null || src.info == null || src.provider == null) {
8499                    continue;
8500                }
8501                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8502                if (DEBUG_MU)
8503                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8504                if (dst != null) {
8505                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8506                    mProviderMap.putProviderByClass(comp, dst);
8507                    String names[] = dst.info.authority.split(";");
8508                    for (int j = 0; j < names.length; j++) {
8509                        mProviderMap.putProviderByName(names[j], dst);
8510                    }
8511
8512                    int NL = mLaunchingProviders.size();
8513                    int j;
8514                    for (j=0; j<NL; j++) {
8515                        if (mLaunchingProviders.get(j) == dst) {
8516                            mLaunchingProviders.remove(j);
8517                            j--;
8518                            NL--;
8519                        }
8520                    }
8521                    synchronized (dst) {
8522                        dst.provider = src.provider;
8523                        dst.proc = r;
8524                        dst.notifyAll();
8525                    }
8526                    updateOomAdjLocked(r);
8527                }
8528            }
8529
8530            Binder.restoreCallingIdentity(origId);
8531        }
8532    }
8533
8534    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8535        ContentProviderConnection conn;
8536        try {
8537            conn = (ContentProviderConnection)connection;
8538        } catch (ClassCastException e) {
8539            String msg ="refContentProvider: " + connection
8540                    + " not a ContentProviderConnection";
8541            Slog.w(TAG, msg);
8542            throw new IllegalArgumentException(msg);
8543        }
8544        if (conn == null) {
8545            throw new NullPointerException("connection is null");
8546        }
8547
8548        synchronized (this) {
8549            if (stable > 0) {
8550                conn.numStableIncs += stable;
8551            }
8552            stable = conn.stableCount + stable;
8553            if (stable < 0) {
8554                throw new IllegalStateException("stableCount < 0: " + stable);
8555            }
8556
8557            if (unstable > 0) {
8558                conn.numUnstableIncs += unstable;
8559            }
8560            unstable = conn.unstableCount + unstable;
8561            if (unstable < 0) {
8562                throw new IllegalStateException("unstableCount < 0: " + unstable);
8563            }
8564
8565            if ((stable+unstable) <= 0) {
8566                throw new IllegalStateException("ref counts can't go to zero here: stable="
8567                        + stable + " unstable=" + unstable);
8568            }
8569            conn.stableCount = stable;
8570            conn.unstableCount = unstable;
8571            return !conn.dead;
8572        }
8573    }
8574
8575    public void unstableProviderDied(IBinder connection) {
8576        ContentProviderConnection conn;
8577        try {
8578            conn = (ContentProviderConnection)connection;
8579        } catch (ClassCastException e) {
8580            String msg ="refContentProvider: " + connection
8581                    + " not a ContentProviderConnection";
8582            Slog.w(TAG, msg);
8583            throw new IllegalArgumentException(msg);
8584        }
8585        if (conn == null) {
8586            throw new NullPointerException("connection is null");
8587        }
8588
8589        // Safely retrieve the content provider associated with the connection.
8590        IContentProvider provider;
8591        synchronized (this) {
8592            provider = conn.provider.provider;
8593        }
8594
8595        if (provider == null) {
8596            // Um, yeah, we're way ahead of you.
8597            return;
8598        }
8599
8600        // Make sure the caller is being honest with us.
8601        if (provider.asBinder().pingBinder()) {
8602            // Er, no, still looks good to us.
8603            synchronized (this) {
8604                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8605                        + " says " + conn + " died, but we don't agree");
8606                return;
8607            }
8608        }
8609
8610        // Well look at that!  It's dead!
8611        synchronized (this) {
8612            if (conn.provider.provider != provider) {
8613                // But something changed...  good enough.
8614                return;
8615            }
8616
8617            ProcessRecord proc = conn.provider.proc;
8618            if (proc == null || proc.thread == null) {
8619                // Seems like the process is already cleaned up.
8620                return;
8621            }
8622
8623            // As far as we're concerned, this is just like receiving a
8624            // death notification...  just a bit prematurely.
8625            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8626                    + ") early provider death");
8627            final long ident = Binder.clearCallingIdentity();
8628            try {
8629                appDiedLocked(proc, proc.pid, proc.thread);
8630            } finally {
8631                Binder.restoreCallingIdentity(ident);
8632            }
8633        }
8634    }
8635
8636    @Override
8637    public void appNotRespondingViaProvider(IBinder connection) {
8638        enforceCallingPermission(
8639                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8640
8641        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8642        if (conn == null) {
8643            Slog.w(TAG, "ContentProviderConnection is null");
8644            return;
8645        }
8646
8647        final ProcessRecord host = conn.provider.proc;
8648        if (host == null) {
8649            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8650            return;
8651        }
8652
8653        final long token = Binder.clearCallingIdentity();
8654        try {
8655            appNotResponding(host, null, null, false, "ContentProvider not responding");
8656        } finally {
8657            Binder.restoreCallingIdentity(token);
8658        }
8659    }
8660
8661    public final void installSystemProviders() {
8662        List<ProviderInfo> providers;
8663        synchronized (this) {
8664            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8665            providers = generateApplicationProvidersLocked(app);
8666            if (providers != null) {
8667                for (int i=providers.size()-1; i>=0; i--) {
8668                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8669                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8670                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8671                                + ": not system .apk");
8672                        providers.remove(i);
8673                    }
8674                }
8675            }
8676        }
8677        if (providers != null) {
8678            mSystemThread.installSystemProviders(providers);
8679        }
8680
8681        mCoreSettingsObserver = new CoreSettingsObserver(this);
8682
8683        mUsageStatsService.monitorPackages();
8684    }
8685
8686    /**
8687     * Allows app to retrieve the MIME type of a URI without having permission
8688     * to access its content provider.
8689     *
8690     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8691     *
8692     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8693     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8694     */
8695    public String getProviderMimeType(Uri uri, int userId) {
8696        enforceNotIsolatedCaller("getProviderMimeType");
8697        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8698                userId, false, true, "getProviderMimeType", null);
8699        final String name = uri.getAuthority();
8700        final long ident = Binder.clearCallingIdentity();
8701        ContentProviderHolder holder = null;
8702
8703        try {
8704            holder = getContentProviderExternalUnchecked(name, null, userId);
8705            if (holder != null) {
8706                return holder.provider.getType(uri);
8707            }
8708        } catch (RemoteException e) {
8709            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8710            return null;
8711        } finally {
8712            if (holder != null) {
8713                removeContentProviderExternalUnchecked(name, null, userId);
8714            }
8715            Binder.restoreCallingIdentity(ident);
8716        }
8717
8718        return null;
8719    }
8720
8721    // =========================================================
8722    // GLOBAL MANAGEMENT
8723    // =========================================================
8724
8725    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8726            boolean isolated) {
8727        String proc = customProcess != null ? customProcess : info.processName;
8728        BatteryStatsImpl.Uid.Proc ps = null;
8729        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8730        int uid = info.uid;
8731        if (isolated) {
8732            int userId = UserHandle.getUserId(uid);
8733            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8734            while (true) {
8735                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8736                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8737                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8738                }
8739                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8740                mNextIsolatedProcessUid++;
8741                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8742                    // No process for this uid, use it.
8743                    break;
8744                }
8745                stepsLeft--;
8746                if (stepsLeft <= 0) {
8747                    return null;
8748                }
8749            }
8750        }
8751        return new ProcessRecord(stats, info, proc, uid);
8752    }
8753
8754    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8755            String abiOverride) {
8756        ProcessRecord app;
8757        if (!isolated) {
8758            app = getProcessRecordLocked(info.processName, info.uid, true);
8759        } else {
8760            app = null;
8761        }
8762
8763        if (app == null) {
8764            app = newProcessRecordLocked(info, null, isolated);
8765            mProcessNames.put(info.processName, app.uid, app);
8766            if (isolated) {
8767                mIsolatedProcesses.put(app.uid, app);
8768            }
8769            updateLruProcessLocked(app, false, null);
8770            updateOomAdjLocked();
8771        }
8772
8773        // This package really, really can not be stopped.
8774        try {
8775            AppGlobals.getPackageManager().setPackageStoppedState(
8776                    info.packageName, false, UserHandle.getUserId(app.uid));
8777        } catch (RemoteException e) {
8778        } catch (IllegalArgumentException e) {
8779            Slog.w(TAG, "Failed trying to unstop package "
8780                    + info.packageName + ": " + e);
8781        }
8782
8783        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8784                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8785            app.persistent = true;
8786            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8787        }
8788        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8789            mPersistentStartingProcesses.add(app);
8790            startProcessLocked(app, "added application", app.processName,
8791                    abiOverride);
8792        }
8793
8794        return app;
8795    }
8796
8797    public void unhandledBack() {
8798        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8799                "unhandledBack()");
8800
8801        synchronized(this) {
8802            final long origId = Binder.clearCallingIdentity();
8803            try {
8804                getFocusedStack().unhandledBackLocked();
8805            } finally {
8806                Binder.restoreCallingIdentity(origId);
8807            }
8808        }
8809    }
8810
8811    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8812        enforceNotIsolatedCaller("openContentUri");
8813        final int userId = UserHandle.getCallingUserId();
8814        String name = uri.getAuthority();
8815        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8816        ParcelFileDescriptor pfd = null;
8817        if (cph != null) {
8818            // We record the binder invoker's uid in thread-local storage before
8819            // going to the content provider to open the file.  Later, in the code
8820            // that handles all permissions checks, we look for this uid and use
8821            // that rather than the Activity Manager's own uid.  The effect is that
8822            // we do the check against the caller's permissions even though it looks
8823            // to the content provider like the Activity Manager itself is making
8824            // the request.
8825            sCallerIdentity.set(new Identity(
8826                    Binder.getCallingPid(), Binder.getCallingUid()));
8827            try {
8828                pfd = cph.provider.openFile(null, uri, "r", null);
8829            } catch (FileNotFoundException e) {
8830                // do nothing; pfd will be returned null
8831            } finally {
8832                // Ensure that whatever happens, we clean up the identity state
8833                sCallerIdentity.remove();
8834            }
8835
8836            // We've got the fd now, so we're done with the provider.
8837            removeContentProviderExternalUnchecked(name, null, userId);
8838        } else {
8839            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8840        }
8841        return pfd;
8842    }
8843
8844    // Actually is sleeping or shutting down or whatever else in the future
8845    // is an inactive state.
8846    public boolean isSleepingOrShuttingDown() {
8847        return mSleeping || mShuttingDown;
8848    }
8849
8850    public boolean isSleeping() {
8851        return mSleeping;
8852    }
8853
8854    void goingToSleep() {
8855        synchronized(this) {
8856            mWentToSleep = true;
8857            updateEventDispatchingLocked();
8858            goToSleepIfNeededLocked();
8859        }
8860    }
8861
8862    void finishRunningVoiceLocked() {
8863        if (mRunningVoice) {
8864            mRunningVoice = false;
8865            goToSleepIfNeededLocked();
8866        }
8867    }
8868
8869    void goToSleepIfNeededLocked() {
8870        if (mWentToSleep && !mRunningVoice) {
8871            if (!mSleeping) {
8872                mSleeping = true;
8873                mStackSupervisor.goingToSleepLocked();
8874
8875                // Initialize the wake times of all processes.
8876                checkExcessivePowerUsageLocked(false);
8877                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8878                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8879                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8880            }
8881        }
8882    }
8883
8884    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8885        mTaskPersister.notify(task, flush);
8886    }
8887
8888    @Override
8889    public boolean shutdown(int timeout) {
8890        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8891                != PackageManager.PERMISSION_GRANTED) {
8892            throw new SecurityException("Requires permission "
8893                    + android.Manifest.permission.SHUTDOWN);
8894        }
8895
8896        boolean timedout = false;
8897
8898        synchronized(this) {
8899            mShuttingDown = true;
8900            updateEventDispatchingLocked();
8901            timedout = mStackSupervisor.shutdownLocked(timeout);
8902        }
8903
8904        mAppOpsService.shutdown();
8905        mUsageStatsService.shutdown();
8906        mBatteryStatsService.shutdown();
8907        synchronized (this) {
8908            mProcessStats.shutdownLocked();
8909        }
8910        notifyTaskPersisterLocked(null, true);
8911
8912        return timedout;
8913    }
8914
8915    public final void activitySlept(IBinder token) {
8916        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8917
8918        final long origId = Binder.clearCallingIdentity();
8919
8920        synchronized (this) {
8921            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8922            if (r != null) {
8923                mStackSupervisor.activitySleptLocked(r);
8924            }
8925        }
8926
8927        Binder.restoreCallingIdentity(origId);
8928    }
8929
8930    void logLockScreen(String msg) {
8931        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8932                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8933                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8934                mStackSupervisor.mDismissKeyguardOnNextActivity);
8935    }
8936
8937    private void comeOutOfSleepIfNeededLocked() {
8938        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8939            if (mSleeping) {
8940                mSleeping = false;
8941                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8942            }
8943        }
8944    }
8945
8946    void wakingUp() {
8947        synchronized(this) {
8948            mWentToSleep = false;
8949            updateEventDispatchingLocked();
8950            comeOutOfSleepIfNeededLocked();
8951        }
8952    }
8953
8954    void startRunningVoiceLocked() {
8955        if (!mRunningVoice) {
8956            mRunningVoice = true;
8957            comeOutOfSleepIfNeededLocked();
8958        }
8959    }
8960
8961    private void updateEventDispatchingLocked() {
8962        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8963    }
8964
8965    public void setLockScreenShown(boolean shown) {
8966        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8967                != PackageManager.PERMISSION_GRANTED) {
8968            throw new SecurityException("Requires permission "
8969                    + android.Manifest.permission.DEVICE_POWER);
8970        }
8971
8972        synchronized(this) {
8973            long ident = Binder.clearCallingIdentity();
8974            try {
8975                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8976                mLockScreenShown = shown;
8977                comeOutOfSleepIfNeededLocked();
8978            } finally {
8979                Binder.restoreCallingIdentity(ident);
8980            }
8981        }
8982    }
8983
8984    public void stopAppSwitches() {
8985        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8986                != PackageManager.PERMISSION_GRANTED) {
8987            throw new SecurityException("Requires permission "
8988                    + android.Manifest.permission.STOP_APP_SWITCHES);
8989        }
8990
8991        synchronized(this) {
8992            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8993                    + APP_SWITCH_DELAY_TIME;
8994            mDidAppSwitch = false;
8995            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8996            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8997            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8998        }
8999    }
9000
9001    public void resumeAppSwitches() {
9002        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9003                != PackageManager.PERMISSION_GRANTED) {
9004            throw new SecurityException("Requires permission "
9005                    + android.Manifest.permission.STOP_APP_SWITCHES);
9006        }
9007
9008        synchronized(this) {
9009            // Note that we don't execute any pending app switches... we will
9010            // let those wait until either the timeout, or the next start
9011            // activity request.
9012            mAppSwitchesAllowedTime = 0;
9013        }
9014    }
9015
9016    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9017            String name) {
9018        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9019            return true;
9020        }
9021
9022        final int perm = checkComponentPermission(
9023                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9024                callingUid, -1, true);
9025        if (perm == PackageManager.PERMISSION_GRANTED) {
9026            return true;
9027        }
9028
9029        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9030        return false;
9031    }
9032
9033    public void setDebugApp(String packageName, boolean waitForDebugger,
9034            boolean persistent) {
9035        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9036                "setDebugApp()");
9037
9038        long ident = Binder.clearCallingIdentity();
9039        try {
9040            // Note that this is not really thread safe if there are multiple
9041            // callers into it at the same time, but that's not a situation we
9042            // care about.
9043            if (persistent) {
9044                final ContentResolver resolver = mContext.getContentResolver();
9045                Settings.Global.putString(
9046                    resolver, Settings.Global.DEBUG_APP,
9047                    packageName);
9048                Settings.Global.putInt(
9049                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9050                    waitForDebugger ? 1 : 0);
9051            }
9052
9053            synchronized (this) {
9054                if (!persistent) {
9055                    mOrigDebugApp = mDebugApp;
9056                    mOrigWaitForDebugger = mWaitForDebugger;
9057                }
9058                mDebugApp = packageName;
9059                mWaitForDebugger = waitForDebugger;
9060                mDebugTransient = !persistent;
9061                if (packageName != null) {
9062                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9063                            false, UserHandle.USER_ALL, "set debug app");
9064                }
9065            }
9066        } finally {
9067            Binder.restoreCallingIdentity(ident);
9068        }
9069    }
9070
9071    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9072        synchronized (this) {
9073            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9074            if (!isDebuggable) {
9075                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9076                    throw new SecurityException("Process not debuggable: " + app.packageName);
9077                }
9078            }
9079
9080            mOpenGlTraceApp = processName;
9081        }
9082    }
9083
9084    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9085            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9086        synchronized (this) {
9087            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9088            if (!isDebuggable) {
9089                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9090                    throw new SecurityException("Process not debuggable: " + app.packageName);
9091                }
9092            }
9093            mProfileApp = processName;
9094            mProfileFile = profileFile;
9095            if (mProfileFd != null) {
9096                try {
9097                    mProfileFd.close();
9098                } catch (IOException e) {
9099                }
9100                mProfileFd = null;
9101            }
9102            mProfileFd = profileFd;
9103            mProfileType = 0;
9104            mAutoStopProfiler = autoStopProfiler;
9105        }
9106    }
9107
9108    @Override
9109    public void setAlwaysFinish(boolean enabled) {
9110        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9111                "setAlwaysFinish()");
9112
9113        Settings.Global.putInt(
9114                mContext.getContentResolver(),
9115                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9116
9117        synchronized (this) {
9118            mAlwaysFinishActivities = enabled;
9119        }
9120    }
9121
9122    @Override
9123    public void setActivityController(IActivityController controller) {
9124        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9125                "setActivityController()");
9126        synchronized (this) {
9127            mController = controller;
9128            Watchdog.getInstance().setActivityController(controller);
9129        }
9130    }
9131
9132    @Override
9133    public void setUserIsMonkey(boolean userIsMonkey) {
9134        synchronized (this) {
9135            synchronized (mPidsSelfLocked) {
9136                final int callingPid = Binder.getCallingPid();
9137                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9138                if (precessRecord == null) {
9139                    throw new SecurityException("Unknown process: " + callingPid);
9140                }
9141                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9142                    throw new SecurityException("Only an instrumentation process "
9143                            + "with a UiAutomation can call setUserIsMonkey");
9144                }
9145            }
9146            mUserIsMonkey = userIsMonkey;
9147        }
9148    }
9149
9150    @Override
9151    public boolean isUserAMonkey() {
9152        synchronized (this) {
9153            // If there is a controller also implies the user is a monkey.
9154            return (mUserIsMonkey || mController != null);
9155        }
9156    }
9157
9158    public void requestBugReport() {
9159        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9160        SystemProperties.set("ctl.start", "bugreport");
9161    }
9162
9163    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9164        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9165    }
9166
9167    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9168        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9169            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9170        }
9171        return KEY_DISPATCHING_TIMEOUT;
9172    }
9173
9174    @Override
9175    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9176        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9177                != PackageManager.PERMISSION_GRANTED) {
9178            throw new SecurityException("Requires permission "
9179                    + android.Manifest.permission.FILTER_EVENTS);
9180        }
9181        ProcessRecord proc;
9182        long timeout;
9183        synchronized (this) {
9184            synchronized (mPidsSelfLocked) {
9185                proc = mPidsSelfLocked.get(pid);
9186            }
9187            timeout = getInputDispatchingTimeoutLocked(proc);
9188        }
9189
9190        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9191            return -1;
9192        }
9193
9194        return timeout;
9195    }
9196
9197    /**
9198     * Handle input dispatching timeouts.
9199     * Returns whether input dispatching should be aborted or not.
9200     */
9201    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9202            final ActivityRecord activity, final ActivityRecord parent,
9203            final boolean aboveSystem, String reason) {
9204        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9205                != PackageManager.PERMISSION_GRANTED) {
9206            throw new SecurityException("Requires permission "
9207                    + android.Manifest.permission.FILTER_EVENTS);
9208        }
9209
9210        final String annotation;
9211        if (reason == null) {
9212            annotation = "Input dispatching timed out";
9213        } else {
9214            annotation = "Input dispatching timed out (" + reason + ")";
9215        }
9216
9217        if (proc != null) {
9218            synchronized (this) {
9219                if (proc.debugging) {
9220                    return false;
9221                }
9222
9223                if (mDidDexOpt) {
9224                    // Give more time since we were dexopting.
9225                    mDidDexOpt = false;
9226                    return false;
9227                }
9228
9229                if (proc.instrumentationClass != null) {
9230                    Bundle info = new Bundle();
9231                    info.putString("shortMsg", "keyDispatchingTimedOut");
9232                    info.putString("longMsg", annotation);
9233                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9234                    return true;
9235                }
9236            }
9237            mHandler.post(new Runnable() {
9238                @Override
9239                public void run() {
9240                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9241                }
9242            });
9243        }
9244
9245        return true;
9246    }
9247
9248    public Bundle getAssistContextExtras(int requestType) {
9249        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9250                "getAssistContextExtras()");
9251        PendingAssistExtras pae;
9252        Bundle extras = new Bundle();
9253        synchronized (this) {
9254            ActivityRecord activity = getFocusedStack().mResumedActivity;
9255            if (activity == null) {
9256                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9257                return null;
9258            }
9259            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9260            if (activity.app == null || activity.app.thread == null) {
9261                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9262                return extras;
9263            }
9264            if (activity.app.pid == Binder.getCallingPid()) {
9265                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9266                return extras;
9267            }
9268            pae = new PendingAssistExtras(activity);
9269            try {
9270                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9271                        requestType);
9272                mPendingAssistExtras.add(pae);
9273                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9274            } catch (RemoteException e) {
9275                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9276                return extras;
9277            }
9278        }
9279        synchronized (pae) {
9280            while (!pae.haveResult) {
9281                try {
9282                    pae.wait();
9283                } catch (InterruptedException e) {
9284                }
9285            }
9286            if (pae.result != null) {
9287                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9288            }
9289        }
9290        synchronized (this) {
9291            mPendingAssistExtras.remove(pae);
9292            mHandler.removeCallbacks(pae);
9293        }
9294        return extras;
9295    }
9296
9297    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9298        PendingAssistExtras pae = (PendingAssistExtras)token;
9299        synchronized (pae) {
9300            pae.result = extras;
9301            pae.haveResult = true;
9302            pae.notifyAll();
9303        }
9304    }
9305
9306    public void registerProcessObserver(IProcessObserver observer) {
9307        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9308                "registerProcessObserver()");
9309        synchronized (this) {
9310            mProcessObservers.register(observer);
9311        }
9312    }
9313
9314    @Override
9315    public void unregisterProcessObserver(IProcessObserver observer) {
9316        synchronized (this) {
9317            mProcessObservers.unregister(observer);
9318        }
9319    }
9320
9321    @Override
9322    public boolean convertFromTranslucent(IBinder token) {
9323        final long origId = Binder.clearCallingIdentity();
9324        try {
9325            synchronized (this) {
9326                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9327                if (r == null) {
9328                    return false;
9329                }
9330                if (r.changeWindowTranslucency(true)) {
9331                    mWindowManager.setAppFullscreen(token, true);
9332                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9333                    return true;
9334                }
9335                return false;
9336            }
9337        } finally {
9338            Binder.restoreCallingIdentity(origId);
9339        }
9340    }
9341
9342    @Override
9343    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9344        final long origId = Binder.clearCallingIdentity();
9345        try {
9346            synchronized (this) {
9347                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9348                if (r == null) {
9349                    return false;
9350                }
9351                if (r.changeWindowTranslucency(false)) {
9352                    r.task.stack.convertToTranslucent(r, options);
9353                    mWindowManager.setAppFullscreen(token, false);
9354                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9355                    return true;
9356                }
9357                return false;
9358            }
9359        } finally {
9360            Binder.restoreCallingIdentity(origId);
9361        }
9362    }
9363
9364    @Override
9365    public ActivityOptions getActivityOptions(IBinder token) {
9366        final long origId = Binder.clearCallingIdentity();
9367        try {
9368            synchronized (this) {
9369                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9370                if (r != null) {
9371                    final ActivityOptions activityOptions = r.pendingOptions;
9372                    r.pendingOptions = null;
9373                    return activityOptions;
9374                }
9375                return null;
9376            }
9377        } finally {
9378            Binder.restoreCallingIdentity(origId);
9379        }
9380    }
9381
9382    @Override
9383    public void setImmersive(IBinder token, boolean immersive) {
9384        synchronized(this) {
9385            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9386            if (r == null) {
9387                throw new IllegalArgumentException();
9388            }
9389            r.immersive = immersive;
9390
9391            // update associated state if we're frontmost
9392            if (r == mFocusedActivity) {
9393                if (DEBUG_IMMERSIVE) {
9394                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9395                }
9396                applyUpdateLockStateLocked(r);
9397            }
9398        }
9399    }
9400
9401    @Override
9402    public boolean isImmersive(IBinder token) {
9403        synchronized (this) {
9404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9405            if (r == null) {
9406                throw new IllegalArgumentException();
9407            }
9408            return r.immersive;
9409        }
9410    }
9411
9412    public boolean isTopActivityImmersive() {
9413        enforceNotIsolatedCaller("startActivity");
9414        synchronized (this) {
9415            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9416            return (r != null) ? r.immersive : false;
9417        }
9418    }
9419
9420    public final void enterSafeMode() {
9421        synchronized(this) {
9422            // It only makes sense to do this before the system is ready
9423            // and started launching other packages.
9424            if (!mSystemReady) {
9425                try {
9426                    AppGlobals.getPackageManager().enterSafeMode();
9427                } catch (RemoteException e) {
9428                }
9429            }
9430
9431            mSafeMode = true;
9432        }
9433    }
9434
9435    public final void showSafeModeOverlay() {
9436        View v = LayoutInflater.from(mContext).inflate(
9437                com.android.internal.R.layout.safe_mode, null);
9438        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9439        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9440        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9441        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9442        lp.gravity = Gravity.BOTTOM | Gravity.START;
9443        lp.format = v.getBackground().getOpacity();
9444        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9445                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9446        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9447        ((WindowManager)mContext.getSystemService(
9448                Context.WINDOW_SERVICE)).addView(v, lp);
9449    }
9450
9451    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9452        if (!(sender instanceof PendingIntentRecord)) {
9453            return;
9454        }
9455        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9456        synchronized (stats) {
9457            if (mBatteryStatsService.isOnBattery()) {
9458                mBatteryStatsService.enforceCallingPermission();
9459                PendingIntentRecord rec = (PendingIntentRecord)sender;
9460                int MY_UID = Binder.getCallingUid();
9461                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9462                BatteryStatsImpl.Uid.Pkg pkg =
9463                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9464                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9465                pkg.incWakeupsLocked();
9466            }
9467        }
9468    }
9469
9470    public boolean killPids(int[] pids, String pReason, boolean secure) {
9471        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9472            throw new SecurityException("killPids only available to the system");
9473        }
9474        String reason = (pReason == null) ? "Unknown" : pReason;
9475        // XXX Note: don't acquire main activity lock here, because the window
9476        // manager calls in with its locks held.
9477
9478        boolean killed = false;
9479        synchronized (mPidsSelfLocked) {
9480            int[] types = new int[pids.length];
9481            int worstType = 0;
9482            for (int i=0; i<pids.length; i++) {
9483                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9484                if (proc != null) {
9485                    int type = proc.setAdj;
9486                    types[i] = type;
9487                    if (type > worstType) {
9488                        worstType = type;
9489                    }
9490                }
9491            }
9492
9493            // If the worst oom_adj is somewhere in the cached proc LRU range,
9494            // then constrain it so we will kill all cached procs.
9495            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9496                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9497                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9498            }
9499
9500            // If this is not a secure call, don't let it kill processes that
9501            // are important.
9502            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9503                worstType = ProcessList.SERVICE_ADJ;
9504            }
9505
9506            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9507            for (int i=0; i<pids.length; i++) {
9508                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9509                if (proc == null) {
9510                    continue;
9511                }
9512                int adj = proc.setAdj;
9513                if (adj >= worstType && !proc.killedByAm) {
9514                    killUnneededProcessLocked(proc, reason);
9515                    killed = true;
9516                }
9517            }
9518        }
9519        return killed;
9520    }
9521
9522    @Override
9523    public void killUid(int uid, String reason) {
9524        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9525            throw new SecurityException("killUid only available to the system");
9526        }
9527        synchronized (this) {
9528            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9529                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9530                    reason != null ? reason : "kill uid");
9531        }
9532    }
9533
9534    @Override
9535    public boolean killProcessesBelowForeground(String reason) {
9536        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9537            throw new SecurityException("killProcessesBelowForeground() only available to system");
9538        }
9539
9540        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9541    }
9542
9543    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9544        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9545            throw new SecurityException("killProcessesBelowAdj() only available to system");
9546        }
9547
9548        boolean killed = false;
9549        synchronized (mPidsSelfLocked) {
9550            final int size = mPidsSelfLocked.size();
9551            for (int i = 0; i < size; i++) {
9552                final int pid = mPidsSelfLocked.keyAt(i);
9553                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9554                if (proc == null) continue;
9555
9556                final int adj = proc.setAdj;
9557                if (adj > belowAdj && !proc.killedByAm) {
9558                    killUnneededProcessLocked(proc, reason);
9559                    killed = true;
9560                }
9561            }
9562        }
9563        return killed;
9564    }
9565
9566    @Override
9567    public void hang(final IBinder who, boolean allowRestart) {
9568        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9569                != PackageManager.PERMISSION_GRANTED) {
9570            throw new SecurityException("Requires permission "
9571                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9572        }
9573
9574        final IBinder.DeathRecipient death = new DeathRecipient() {
9575            @Override
9576            public void binderDied() {
9577                synchronized (this) {
9578                    notifyAll();
9579                }
9580            }
9581        };
9582
9583        try {
9584            who.linkToDeath(death, 0);
9585        } catch (RemoteException e) {
9586            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9587            return;
9588        }
9589
9590        synchronized (this) {
9591            Watchdog.getInstance().setAllowRestart(allowRestart);
9592            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9593            synchronized (death) {
9594                while (who.isBinderAlive()) {
9595                    try {
9596                        death.wait();
9597                    } catch (InterruptedException e) {
9598                    }
9599                }
9600            }
9601            Watchdog.getInstance().setAllowRestart(true);
9602        }
9603    }
9604
9605    @Override
9606    public void restart() {
9607        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9608                != PackageManager.PERMISSION_GRANTED) {
9609            throw new SecurityException("Requires permission "
9610                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9611        }
9612
9613        Log.i(TAG, "Sending shutdown broadcast...");
9614
9615        BroadcastReceiver br = new BroadcastReceiver() {
9616            @Override public void onReceive(Context context, Intent intent) {
9617                // Now the broadcast is done, finish up the low-level shutdown.
9618                Log.i(TAG, "Shutting down activity manager...");
9619                shutdown(10000);
9620                Log.i(TAG, "Shutdown complete, restarting!");
9621                Process.killProcess(Process.myPid());
9622                System.exit(10);
9623            }
9624        };
9625
9626        // First send the high-level shut down broadcast.
9627        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9628        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9629        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9630        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9631        mContext.sendOrderedBroadcastAsUser(intent,
9632                UserHandle.ALL, null, br, mHandler, 0, null, null);
9633        */
9634        br.onReceive(mContext, intent);
9635    }
9636
9637    private long getLowRamTimeSinceIdle(long now) {
9638        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9639    }
9640
9641    @Override
9642    public void performIdleMaintenance() {
9643        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9644                != PackageManager.PERMISSION_GRANTED) {
9645            throw new SecurityException("Requires permission "
9646                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9647        }
9648
9649        synchronized (this) {
9650            final long now = SystemClock.uptimeMillis();
9651            final long timeSinceLastIdle = now - mLastIdleTime;
9652            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9653            mLastIdleTime = now;
9654            mLowRamTimeSinceLastIdle = 0;
9655            if (mLowRamStartTime != 0) {
9656                mLowRamStartTime = now;
9657            }
9658
9659            StringBuilder sb = new StringBuilder(128);
9660            sb.append("Idle maintenance over ");
9661            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9662            sb.append(" low RAM for ");
9663            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9664            Slog.i(TAG, sb.toString());
9665
9666            // If at least 1/3 of our time since the last idle period has been spent
9667            // with RAM low, then we want to kill processes.
9668            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9669
9670            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9671                ProcessRecord proc = mLruProcesses.get(i);
9672                if (proc.notCachedSinceIdle) {
9673                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9674                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9675                        if (doKilling && proc.initialIdlePss != 0
9676                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9677                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9678                                    + " from " + proc.initialIdlePss + ")");
9679                        }
9680                    }
9681                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9682                    proc.notCachedSinceIdle = true;
9683                    proc.initialIdlePss = 0;
9684                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9685                            isSleeping(), now);
9686                }
9687            }
9688
9689            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9690            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9691        }
9692    }
9693
9694    private void retrieveSettings() {
9695        final ContentResolver resolver = mContext.getContentResolver();
9696        String debugApp = Settings.Global.getString(
9697            resolver, Settings.Global.DEBUG_APP);
9698        boolean waitForDebugger = Settings.Global.getInt(
9699            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9700        boolean alwaysFinishActivities = Settings.Global.getInt(
9701            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9702        boolean forceRtl = Settings.Global.getInt(
9703                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9704        // Transfer any global setting for forcing RTL layout, into a System Property
9705        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9706
9707        Configuration configuration = new Configuration();
9708        Settings.System.getConfiguration(resolver, configuration);
9709        if (forceRtl) {
9710            // This will take care of setting the correct layout direction flags
9711            configuration.setLayoutDirection(configuration.locale);
9712        }
9713
9714        synchronized (this) {
9715            mDebugApp = mOrigDebugApp = debugApp;
9716            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9717            mAlwaysFinishActivities = alwaysFinishActivities;
9718            // This happens before any activities are started, so we can
9719            // change mConfiguration in-place.
9720            updateConfigurationLocked(configuration, null, false, true);
9721            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9722        }
9723    }
9724
9725    public boolean testIsSystemReady() {
9726        // no need to synchronize(this) just to read & return the value
9727        return mSystemReady;
9728    }
9729
9730    private static File getCalledPreBootReceiversFile() {
9731        File dataDir = Environment.getDataDirectory();
9732        File systemDir = new File(dataDir, "system");
9733        File fname = new File(systemDir, "called_pre_boots.dat");
9734        return fname;
9735    }
9736
9737    static final int LAST_DONE_VERSION = 10000;
9738
9739    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9740        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9741        File file = getCalledPreBootReceiversFile();
9742        FileInputStream fis = null;
9743        try {
9744            fis = new FileInputStream(file);
9745            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9746            int fvers = dis.readInt();
9747            if (fvers == LAST_DONE_VERSION) {
9748                String vers = dis.readUTF();
9749                String codename = dis.readUTF();
9750                String build = dis.readUTF();
9751                if (android.os.Build.VERSION.RELEASE.equals(vers)
9752                        && android.os.Build.VERSION.CODENAME.equals(codename)
9753                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9754                    int num = dis.readInt();
9755                    while (num > 0) {
9756                        num--;
9757                        String pkg = dis.readUTF();
9758                        String cls = dis.readUTF();
9759                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9760                    }
9761                }
9762            }
9763        } catch (FileNotFoundException e) {
9764        } catch (IOException e) {
9765            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9766        } finally {
9767            if (fis != null) {
9768                try {
9769                    fis.close();
9770                } catch (IOException e) {
9771                }
9772            }
9773        }
9774        return lastDoneReceivers;
9775    }
9776
9777    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9778        File file = getCalledPreBootReceiversFile();
9779        FileOutputStream fos = null;
9780        DataOutputStream dos = null;
9781        try {
9782            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9783            fos = new FileOutputStream(file);
9784            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9785            dos.writeInt(LAST_DONE_VERSION);
9786            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9787            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9788            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9789            dos.writeInt(list.size());
9790            for (int i=0; i<list.size(); i++) {
9791                dos.writeUTF(list.get(i).getPackageName());
9792                dos.writeUTF(list.get(i).getClassName());
9793            }
9794        } catch (IOException e) {
9795            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9796            file.delete();
9797        } finally {
9798            FileUtils.sync(fos);
9799            if (dos != null) {
9800                try {
9801                    dos.close();
9802                } catch (IOException e) {
9803                    // TODO Auto-generated catch block
9804                    e.printStackTrace();
9805                }
9806            }
9807        }
9808    }
9809
9810    public void systemReady(final Runnable goingCallback) {
9811        synchronized(this) {
9812            if (mSystemReady) {
9813                if (goingCallback != null) goingCallback.run();
9814                return;
9815            }
9816
9817            if (mRecentTasks == null) {
9818                mRecentTasks = mTaskPersister.restoreTasksLocked();
9819                if (!mRecentTasks.isEmpty()) {
9820                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9821                }
9822                mTaskPersister.startPersisting();
9823            }
9824
9825            // Check to see if there are any update receivers to run.
9826            if (!mDidUpdate) {
9827                if (mWaitingUpdate) {
9828                    return;
9829                }
9830                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9831                List<ResolveInfo> ris = null;
9832                try {
9833                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9834                            intent, null, 0, 0);
9835                } catch (RemoteException e) {
9836                }
9837                if (ris != null) {
9838                    for (int i=ris.size()-1; i>=0; i--) {
9839                        if ((ris.get(i).activityInfo.applicationInfo.flags
9840                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9841                            ris.remove(i);
9842                        }
9843                    }
9844                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9845
9846                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9847
9848                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9849                    for (int i=0; i<ris.size(); i++) {
9850                        ActivityInfo ai = ris.get(i).activityInfo;
9851                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9852                        if (lastDoneReceivers.contains(comp)) {
9853                            // We already did the pre boot receiver for this app with the current
9854                            // platform version, so don't do it again...
9855                            ris.remove(i);
9856                            i--;
9857                            // ...however, do keep it as one that has been done, so we don't
9858                            // forget about it when rewriting the file of last done receivers.
9859                            doneReceivers.add(comp);
9860                        }
9861                    }
9862
9863                    final int[] users = getUsersLocked();
9864                    for (int i=0; i<ris.size(); i++) {
9865                        ActivityInfo ai = ris.get(i).activityInfo;
9866                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9867                        doneReceivers.add(comp);
9868                        intent.setComponent(comp);
9869                        for (int j=0; j<users.length; j++) {
9870                            IIntentReceiver finisher = null;
9871                            if (i == ris.size()-1 && j == users.length-1) {
9872                                finisher = new IIntentReceiver.Stub() {
9873                                    public void performReceive(Intent intent, int resultCode,
9874                                            String data, Bundle extras, boolean ordered,
9875                                            boolean sticky, int sendingUser) {
9876                                        // The raw IIntentReceiver interface is called
9877                                        // with the AM lock held, so redispatch to
9878                                        // execute our code without the lock.
9879                                        mHandler.post(new Runnable() {
9880                                            public void run() {
9881                                                synchronized (ActivityManagerService.this) {
9882                                                    mDidUpdate = true;
9883                                                }
9884                                                writeLastDonePreBootReceivers(doneReceivers);
9885                                                showBootMessage(mContext.getText(
9886                                                        R.string.android_upgrading_complete),
9887                                                        false);
9888                                                systemReady(goingCallback);
9889                                            }
9890                                        });
9891                                    }
9892                                };
9893                            }
9894                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9895                                    + " for user " + users[j]);
9896                            broadcastIntentLocked(null, null, intent, null, finisher,
9897                                    0, null, null, null, AppOpsManager.OP_NONE,
9898                                    true, false, MY_PID, Process.SYSTEM_UID,
9899                                    users[j]);
9900                            if (finisher != null) {
9901                                mWaitingUpdate = true;
9902                            }
9903                        }
9904                    }
9905                }
9906                if (mWaitingUpdate) {
9907                    return;
9908                }
9909                mDidUpdate = true;
9910            }
9911
9912            mAppOpsService.systemReady();
9913            mUsageStatsService.systemReady();
9914            mSystemReady = true;
9915        }
9916
9917        ArrayList<ProcessRecord> procsToKill = null;
9918        synchronized(mPidsSelfLocked) {
9919            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9920                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9921                if (!isAllowedWhileBooting(proc.info)){
9922                    if (procsToKill == null) {
9923                        procsToKill = new ArrayList<ProcessRecord>();
9924                    }
9925                    procsToKill.add(proc);
9926                }
9927            }
9928        }
9929
9930        synchronized(this) {
9931            if (procsToKill != null) {
9932                for (int i=procsToKill.size()-1; i>=0; i--) {
9933                    ProcessRecord proc = procsToKill.get(i);
9934                    Slog.i(TAG, "Removing system update proc: " + proc);
9935                    removeProcessLocked(proc, true, false, "system update done");
9936                }
9937            }
9938
9939            // Now that we have cleaned up any update processes, we
9940            // are ready to start launching real processes and know that
9941            // we won't trample on them any more.
9942            mProcessesReady = true;
9943        }
9944
9945        Slog.i(TAG, "System now ready");
9946        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9947            SystemClock.uptimeMillis());
9948
9949        synchronized(this) {
9950            // Make sure we have no pre-ready processes sitting around.
9951
9952            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9953                ResolveInfo ri = mContext.getPackageManager()
9954                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9955                                STOCK_PM_FLAGS);
9956                CharSequence errorMsg = null;
9957                if (ri != null) {
9958                    ActivityInfo ai = ri.activityInfo;
9959                    ApplicationInfo app = ai.applicationInfo;
9960                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9961                        mTopAction = Intent.ACTION_FACTORY_TEST;
9962                        mTopData = null;
9963                        mTopComponent = new ComponentName(app.packageName,
9964                                ai.name);
9965                    } else {
9966                        errorMsg = mContext.getResources().getText(
9967                                com.android.internal.R.string.factorytest_not_system);
9968                    }
9969                } else {
9970                    errorMsg = mContext.getResources().getText(
9971                            com.android.internal.R.string.factorytest_no_action);
9972                }
9973                if (errorMsg != null) {
9974                    mTopAction = null;
9975                    mTopData = null;
9976                    mTopComponent = null;
9977                    Message msg = Message.obtain();
9978                    msg.what = SHOW_FACTORY_ERROR_MSG;
9979                    msg.getData().putCharSequence("msg", errorMsg);
9980                    mHandler.sendMessage(msg);
9981                }
9982            }
9983        }
9984
9985        retrieveSettings();
9986
9987        synchronized (this) {
9988            readGrantedUriPermissionsLocked();
9989        }
9990
9991        if (goingCallback != null) goingCallback.run();
9992
9993        mSystemServiceManager.startUser(mCurrentUserId);
9994
9995        synchronized (this) {
9996            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9997                try {
9998                    List apps = AppGlobals.getPackageManager().
9999                        getPersistentApplications(STOCK_PM_FLAGS);
10000                    if (apps != null) {
10001                        int N = apps.size();
10002                        int i;
10003                        for (i=0; i<N; i++) {
10004                            ApplicationInfo info
10005                                = (ApplicationInfo)apps.get(i);
10006                            if (info != null &&
10007                                    !info.packageName.equals("android")) {
10008                                addAppLocked(info, false, null /* ABI override */);
10009                            }
10010                        }
10011                    }
10012                } catch (RemoteException ex) {
10013                    // pm is in same process, this will never happen.
10014                }
10015            }
10016
10017            // Start up initial activity.
10018            mBooting = true;
10019
10020            try {
10021                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10022                    Message msg = Message.obtain();
10023                    msg.what = SHOW_UID_ERROR_MSG;
10024                    mHandler.sendMessage(msg);
10025                }
10026            } catch (RemoteException e) {
10027            }
10028
10029            long ident = Binder.clearCallingIdentity();
10030            try {
10031                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10032                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10033                        | Intent.FLAG_RECEIVER_FOREGROUND);
10034                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10035                broadcastIntentLocked(null, null, intent,
10036                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10037                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10038                intent = new Intent(Intent.ACTION_USER_STARTING);
10039                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10040                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10041                broadcastIntentLocked(null, null, intent,
10042                        null, new IIntentReceiver.Stub() {
10043                            @Override
10044                            public void performReceive(Intent intent, int resultCode, String data,
10045                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10046                                    throws RemoteException {
10047                            }
10048                        }, 0, null, null,
10049                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10050                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10051            } catch (Throwable t) {
10052                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10053            } finally {
10054                Binder.restoreCallingIdentity(ident);
10055            }
10056            mStackSupervisor.resumeTopActivitiesLocked();
10057            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10058        }
10059    }
10060
10061    private boolean makeAppCrashingLocked(ProcessRecord app,
10062            String shortMsg, String longMsg, String stackTrace) {
10063        app.crashing = true;
10064        app.crashingReport = generateProcessError(app,
10065                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10066        startAppProblemLocked(app);
10067        app.stopFreezingAllLocked();
10068        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10069    }
10070
10071    private void makeAppNotRespondingLocked(ProcessRecord app,
10072            String activity, String shortMsg, String longMsg) {
10073        app.notResponding = true;
10074        app.notRespondingReport = generateProcessError(app,
10075                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10076                activity, shortMsg, longMsg, null);
10077        startAppProblemLocked(app);
10078        app.stopFreezingAllLocked();
10079    }
10080
10081    /**
10082     * Generate a process error record, suitable for attachment to a ProcessRecord.
10083     *
10084     * @param app The ProcessRecord in which the error occurred.
10085     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10086     *                      ActivityManager.AppErrorStateInfo
10087     * @param activity The activity associated with the crash, if known.
10088     * @param shortMsg Short message describing the crash.
10089     * @param longMsg Long message describing the crash.
10090     * @param stackTrace Full crash stack trace, may be null.
10091     *
10092     * @return Returns a fully-formed AppErrorStateInfo record.
10093     */
10094    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10095            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10096        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10097
10098        report.condition = condition;
10099        report.processName = app.processName;
10100        report.pid = app.pid;
10101        report.uid = app.info.uid;
10102        report.tag = activity;
10103        report.shortMsg = shortMsg;
10104        report.longMsg = longMsg;
10105        report.stackTrace = stackTrace;
10106
10107        return report;
10108    }
10109
10110    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10111        synchronized (this) {
10112            app.crashing = false;
10113            app.crashingReport = null;
10114            app.notResponding = false;
10115            app.notRespondingReport = null;
10116            if (app.anrDialog == fromDialog) {
10117                app.anrDialog = null;
10118            }
10119            if (app.waitDialog == fromDialog) {
10120                app.waitDialog = null;
10121            }
10122            if (app.pid > 0 && app.pid != MY_PID) {
10123                handleAppCrashLocked(app, null, null, null);
10124                killUnneededProcessLocked(app, "user request after error");
10125            }
10126        }
10127    }
10128
10129    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10130            String stackTrace) {
10131        long now = SystemClock.uptimeMillis();
10132
10133        Long crashTime;
10134        if (!app.isolated) {
10135            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10136        } else {
10137            crashTime = null;
10138        }
10139        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10140            // This process loses!
10141            Slog.w(TAG, "Process " + app.info.processName
10142                    + " has crashed too many times: killing!");
10143            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10144                    app.userId, app.info.processName, app.uid);
10145            mStackSupervisor.handleAppCrashLocked(app);
10146            if (!app.persistent) {
10147                // We don't want to start this process again until the user
10148                // explicitly does so...  but for persistent process, we really
10149                // need to keep it running.  If a persistent process is actually
10150                // repeatedly crashing, then badness for everyone.
10151                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10152                        app.info.processName);
10153                if (!app.isolated) {
10154                    // XXX We don't have a way to mark isolated processes
10155                    // as bad, since they don't have a peristent identity.
10156                    mBadProcesses.put(app.info.processName, app.uid,
10157                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10158                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10159                }
10160                app.bad = true;
10161                app.removed = true;
10162                // Don't let services in this process be restarted and potentially
10163                // annoy the user repeatedly.  Unless it is persistent, since those
10164                // processes run critical code.
10165                removeProcessLocked(app, false, false, "crash");
10166                mStackSupervisor.resumeTopActivitiesLocked();
10167                return false;
10168            }
10169            mStackSupervisor.resumeTopActivitiesLocked();
10170        } else {
10171            mStackSupervisor.finishTopRunningActivityLocked(app);
10172        }
10173
10174        // Bump up the crash count of any services currently running in the proc.
10175        for (int i=app.services.size()-1; i>=0; i--) {
10176            // Any services running in the application need to be placed
10177            // back in the pending list.
10178            ServiceRecord sr = app.services.valueAt(i);
10179            sr.crashCount++;
10180        }
10181
10182        // If the crashing process is what we consider to be the "home process" and it has been
10183        // replaced by a third-party app, clear the package preferred activities from packages
10184        // with a home activity running in the process to prevent a repeatedly crashing app
10185        // from blocking the user to manually clear the list.
10186        final ArrayList<ActivityRecord> activities = app.activities;
10187        if (app == mHomeProcess && activities.size() > 0
10188                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10189            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10190                final ActivityRecord r = activities.get(activityNdx);
10191                if (r.isHomeActivity()) {
10192                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10193                    try {
10194                        ActivityThread.getPackageManager()
10195                                .clearPackagePreferredActivities(r.packageName);
10196                    } catch (RemoteException c) {
10197                        // pm is in same process, this will never happen.
10198                    }
10199                }
10200            }
10201        }
10202
10203        if (!app.isolated) {
10204            // XXX Can't keep track of crash times for isolated processes,
10205            // because they don't have a perisistent identity.
10206            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10207        }
10208
10209        return true;
10210    }
10211
10212    void startAppProblemLocked(ProcessRecord app) {
10213        if (app.userId == mCurrentUserId) {
10214            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10215                    mContext, app.info.packageName, app.info.flags);
10216        } else {
10217            // If this app is not running under the current user, then we
10218            // can't give it a report button because that would require
10219            // launching the report UI under a different user.
10220            app.errorReportReceiver = null;
10221        }
10222        skipCurrentReceiverLocked(app);
10223    }
10224
10225    void skipCurrentReceiverLocked(ProcessRecord app) {
10226        for (BroadcastQueue queue : mBroadcastQueues) {
10227            queue.skipCurrentReceiverLocked(app);
10228        }
10229    }
10230
10231    /**
10232     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10233     * The application process will exit immediately after this call returns.
10234     * @param app object of the crashing app, null for the system server
10235     * @param crashInfo describing the exception
10236     */
10237    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10238        ProcessRecord r = findAppProcess(app, "Crash");
10239        final String processName = app == null ? "system_server"
10240                : (r == null ? "unknown" : r.processName);
10241
10242        handleApplicationCrashInner("crash", r, processName, crashInfo);
10243    }
10244
10245    /* Native crash reporting uses this inner version because it needs to be somewhat
10246     * decoupled from the AM-managed cleanup lifecycle
10247     */
10248    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10249            ApplicationErrorReport.CrashInfo crashInfo) {
10250        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10251                UserHandle.getUserId(Binder.getCallingUid()), processName,
10252                r == null ? -1 : r.info.flags,
10253                crashInfo.exceptionClassName,
10254                crashInfo.exceptionMessage,
10255                crashInfo.throwFileName,
10256                crashInfo.throwLineNumber);
10257
10258        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10259
10260        crashApplication(r, crashInfo);
10261    }
10262
10263    public void handleApplicationStrictModeViolation(
10264            IBinder app,
10265            int violationMask,
10266            StrictMode.ViolationInfo info) {
10267        ProcessRecord r = findAppProcess(app, "StrictMode");
10268        if (r == null) {
10269            return;
10270        }
10271
10272        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10273            Integer stackFingerprint = info.hashCode();
10274            boolean logIt = true;
10275            synchronized (mAlreadyLoggedViolatedStacks) {
10276                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10277                    logIt = false;
10278                    // TODO: sub-sample into EventLog for these, with
10279                    // the info.durationMillis?  Then we'd get
10280                    // the relative pain numbers, without logging all
10281                    // the stack traces repeatedly.  We'd want to do
10282                    // likewise in the client code, which also does
10283                    // dup suppression, before the Binder call.
10284                } else {
10285                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10286                        mAlreadyLoggedViolatedStacks.clear();
10287                    }
10288                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10289                }
10290            }
10291            if (logIt) {
10292                logStrictModeViolationToDropBox(r, info);
10293            }
10294        }
10295
10296        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10297            AppErrorResult result = new AppErrorResult();
10298            synchronized (this) {
10299                final long origId = Binder.clearCallingIdentity();
10300
10301                Message msg = Message.obtain();
10302                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10303                HashMap<String, Object> data = new HashMap<String, Object>();
10304                data.put("result", result);
10305                data.put("app", r);
10306                data.put("violationMask", violationMask);
10307                data.put("info", info);
10308                msg.obj = data;
10309                mHandler.sendMessage(msg);
10310
10311                Binder.restoreCallingIdentity(origId);
10312            }
10313            int res = result.get();
10314            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10315        }
10316    }
10317
10318    // Depending on the policy in effect, there could be a bunch of
10319    // these in quick succession so we try to batch these together to
10320    // minimize disk writes, number of dropbox entries, and maximize
10321    // compression, by having more fewer, larger records.
10322    private void logStrictModeViolationToDropBox(
10323            ProcessRecord process,
10324            StrictMode.ViolationInfo info) {
10325        if (info == null) {
10326            return;
10327        }
10328        final boolean isSystemApp = process == null ||
10329                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10330                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10331        final String processName = process == null ? "unknown" : process.processName;
10332        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10333        final DropBoxManager dbox = (DropBoxManager)
10334                mContext.getSystemService(Context.DROPBOX_SERVICE);
10335
10336        // Exit early if the dropbox isn't configured to accept this report type.
10337        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10338
10339        boolean bufferWasEmpty;
10340        boolean needsFlush;
10341        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10342        synchronized (sb) {
10343            bufferWasEmpty = sb.length() == 0;
10344            appendDropBoxProcessHeaders(process, processName, sb);
10345            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10346            sb.append("System-App: ").append(isSystemApp).append("\n");
10347            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10348            if (info.violationNumThisLoop != 0) {
10349                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10350            }
10351            if (info.numAnimationsRunning != 0) {
10352                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10353            }
10354            if (info.broadcastIntentAction != null) {
10355                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10356            }
10357            if (info.durationMillis != -1) {
10358                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10359            }
10360            if (info.numInstances != -1) {
10361                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10362            }
10363            if (info.tags != null) {
10364                for (String tag : info.tags) {
10365                    sb.append("Span-Tag: ").append(tag).append("\n");
10366                }
10367            }
10368            sb.append("\n");
10369            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10370                sb.append(info.crashInfo.stackTrace);
10371            }
10372            sb.append("\n");
10373
10374            // Only buffer up to ~64k.  Various logging bits truncate
10375            // things at 128k.
10376            needsFlush = (sb.length() > 64 * 1024);
10377        }
10378
10379        // Flush immediately if the buffer's grown too large, or this
10380        // is a non-system app.  Non-system apps are isolated with a
10381        // different tag & policy and not batched.
10382        //
10383        // Batching is useful during internal testing with
10384        // StrictMode settings turned up high.  Without batching,
10385        // thousands of separate files could be created on boot.
10386        if (!isSystemApp || needsFlush) {
10387            new Thread("Error dump: " + dropboxTag) {
10388                @Override
10389                public void run() {
10390                    String report;
10391                    synchronized (sb) {
10392                        report = sb.toString();
10393                        sb.delete(0, sb.length());
10394                        sb.trimToSize();
10395                    }
10396                    if (report.length() != 0) {
10397                        dbox.addText(dropboxTag, report);
10398                    }
10399                }
10400            }.start();
10401            return;
10402        }
10403
10404        // System app batching:
10405        if (!bufferWasEmpty) {
10406            // An existing dropbox-writing thread is outstanding, so
10407            // we don't need to start it up.  The existing thread will
10408            // catch the buffer appends we just did.
10409            return;
10410        }
10411
10412        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10413        // (After this point, we shouldn't access AMS internal data structures.)
10414        new Thread("Error dump: " + dropboxTag) {
10415            @Override
10416            public void run() {
10417                // 5 second sleep to let stacks arrive and be batched together
10418                try {
10419                    Thread.sleep(5000);  // 5 seconds
10420                } catch (InterruptedException e) {}
10421
10422                String errorReport;
10423                synchronized (mStrictModeBuffer) {
10424                    errorReport = mStrictModeBuffer.toString();
10425                    if (errorReport.length() == 0) {
10426                        return;
10427                    }
10428                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10429                    mStrictModeBuffer.trimToSize();
10430                }
10431                dbox.addText(dropboxTag, errorReport);
10432            }
10433        }.start();
10434    }
10435
10436    /**
10437     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10438     * @param app object of the crashing app, null for the system server
10439     * @param tag reported by the caller
10440     * @param crashInfo describing the context of the error
10441     * @return true if the process should exit immediately (WTF is fatal)
10442     */
10443    public boolean handleApplicationWtf(IBinder app, String tag,
10444            ApplicationErrorReport.CrashInfo crashInfo) {
10445        ProcessRecord r = findAppProcess(app, "WTF");
10446        final String processName = app == null ? "system_server"
10447                : (r == null ? "unknown" : r.processName);
10448
10449        EventLog.writeEvent(EventLogTags.AM_WTF,
10450                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10451                processName,
10452                r == null ? -1 : r.info.flags,
10453                tag, crashInfo.exceptionMessage);
10454
10455        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10456
10457        if (r != null && r.pid != Process.myPid() &&
10458                Settings.Global.getInt(mContext.getContentResolver(),
10459                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10460            crashApplication(r, crashInfo);
10461            return true;
10462        } else {
10463            return false;
10464        }
10465    }
10466
10467    /**
10468     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10469     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10470     */
10471    private ProcessRecord findAppProcess(IBinder app, String reason) {
10472        if (app == null) {
10473            return null;
10474        }
10475
10476        synchronized (this) {
10477            final int NP = mProcessNames.getMap().size();
10478            for (int ip=0; ip<NP; ip++) {
10479                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10480                final int NA = apps.size();
10481                for (int ia=0; ia<NA; ia++) {
10482                    ProcessRecord p = apps.valueAt(ia);
10483                    if (p.thread != null && p.thread.asBinder() == app) {
10484                        return p;
10485                    }
10486                }
10487            }
10488
10489            Slog.w(TAG, "Can't find mystery application for " + reason
10490                    + " from pid=" + Binder.getCallingPid()
10491                    + " uid=" + Binder.getCallingUid() + ": " + app);
10492            return null;
10493        }
10494    }
10495
10496    /**
10497     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10498     * to append various headers to the dropbox log text.
10499     */
10500    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10501            StringBuilder sb) {
10502        // Watchdog thread ends up invoking this function (with
10503        // a null ProcessRecord) to add the stack file to dropbox.
10504        // Do not acquire a lock on this (am) in such cases, as it
10505        // could cause a potential deadlock, if and when watchdog
10506        // is invoked due to unavailability of lock on am and it
10507        // would prevent watchdog from killing system_server.
10508        if (process == null) {
10509            sb.append("Process: ").append(processName).append("\n");
10510            return;
10511        }
10512        // Note: ProcessRecord 'process' is guarded by the service
10513        // instance.  (notably process.pkgList, which could otherwise change
10514        // concurrently during execution of this method)
10515        synchronized (this) {
10516            sb.append("Process: ").append(processName).append("\n");
10517            int flags = process.info.flags;
10518            IPackageManager pm = AppGlobals.getPackageManager();
10519            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10520            for (int ip=0; ip<process.pkgList.size(); ip++) {
10521                String pkg = process.pkgList.keyAt(ip);
10522                sb.append("Package: ").append(pkg);
10523                try {
10524                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10525                    if (pi != null) {
10526                        sb.append(" v").append(pi.versionCode);
10527                        if (pi.versionName != null) {
10528                            sb.append(" (").append(pi.versionName).append(")");
10529                        }
10530                    }
10531                } catch (RemoteException e) {
10532                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10533                }
10534                sb.append("\n");
10535            }
10536        }
10537    }
10538
10539    private static String processClass(ProcessRecord process) {
10540        if (process == null || process.pid == MY_PID) {
10541            return "system_server";
10542        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10543            return "system_app";
10544        } else {
10545            return "data_app";
10546        }
10547    }
10548
10549    /**
10550     * Write a description of an error (crash, WTF, ANR) to the drop box.
10551     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10552     * @param process which caused the error, null means the system server
10553     * @param activity which triggered the error, null if unknown
10554     * @param parent activity related to the error, null if unknown
10555     * @param subject line related to the error, null if absent
10556     * @param report in long form describing the error, null if absent
10557     * @param logFile to include in the report, null if none
10558     * @param crashInfo giving an application stack trace, null if absent
10559     */
10560    public void addErrorToDropBox(String eventType,
10561            ProcessRecord process, String processName, ActivityRecord activity,
10562            ActivityRecord parent, String subject,
10563            final String report, final File logFile,
10564            final ApplicationErrorReport.CrashInfo crashInfo) {
10565        // NOTE -- this must never acquire the ActivityManagerService lock,
10566        // otherwise the watchdog may be prevented from resetting the system.
10567
10568        final String dropboxTag = processClass(process) + "_" + eventType;
10569        final DropBoxManager dbox = (DropBoxManager)
10570                mContext.getSystemService(Context.DROPBOX_SERVICE);
10571
10572        // Exit early if the dropbox isn't configured to accept this report type.
10573        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10574
10575        final StringBuilder sb = new StringBuilder(1024);
10576        appendDropBoxProcessHeaders(process, processName, sb);
10577        if (activity != null) {
10578            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10579        }
10580        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10581            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10582        }
10583        if (parent != null && parent != activity) {
10584            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10585        }
10586        if (subject != null) {
10587            sb.append("Subject: ").append(subject).append("\n");
10588        }
10589        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10590        if (Debug.isDebuggerConnected()) {
10591            sb.append("Debugger: Connected\n");
10592        }
10593        sb.append("\n");
10594
10595        // Do the rest in a worker thread to avoid blocking the caller on I/O
10596        // (After this point, we shouldn't access AMS internal data structures.)
10597        Thread worker = new Thread("Error dump: " + dropboxTag) {
10598            @Override
10599            public void run() {
10600                if (report != null) {
10601                    sb.append(report);
10602                }
10603                if (logFile != null) {
10604                    try {
10605                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10606                                    "\n\n[[TRUNCATED]]"));
10607                    } catch (IOException e) {
10608                        Slog.e(TAG, "Error reading " + logFile, e);
10609                    }
10610                }
10611                if (crashInfo != null && crashInfo.stackTrace != null) {
10612                    sb.append(crashInfo.stackTrace);
10613                }
10614
10615                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10616                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10617                if (lines > 0) {
10618                    sb.append("\n");
10619
10620                    // Merge several logcat streams, and take the last N lines
10621                    InputStreamReader input = null;
10622                    try {
10623                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10624                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10625                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10626
10627                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10628                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10629                        input = new InputStreamReader(logcat.getInputStream());
10630
10631                        int num;
10632                        char[] buf = new char[8192];
10633                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10634                    } catch (IOException e) {
10635                        Slog.e(TAG, "Error running logcat", e);
10636                    } finally {
10637                        if (input != null) try { input.close(); } catch (IOException e) {}
10638                    }
10639                }
10640
10641                dbox.addText(dropboxTag, sb.toString());
10642            }
10643        };
10644
10645        if (process == null) {
10646            // If process is null, we are being called from some internal code
10647            // and may be about to die -- run this synchronously.
10648            worker.run();
10649        } else {
10650            worker.start();
10651        }
10652    }
10653
10654    /**
10655     * Bring up the "unexpected error" dialog box for a crashing app.
10656     * Deal with edge cases (intercepts from instrumented applications,
10657     * ActivityController, error intent receivers, that sort of thing).
10658     * @param r the application crashing
10659     * @param crashInfo describing the failure
10660     */
10661    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10662        long timeMillis = System.currentTimeMillis();
10663        String shortMsg = crashInfo.exceptionClassName;
10664        String longMsg = crashInfo.exceptionMessage;
10665        String stackTrace = crashInfo.stackTrace;
10666        if (shortMsg != null && longMsg != null) {
10667            longMsg = shortMsg + ": " + longMsg;
10668        } else if (shortMsg != null) {
10669            longMsg = shortMsg;
10670        }
10671
10672        AppErrorResult result = new AppErrorResult();
10673        synchronized (this) {
10674            if (mController != null) {
10675                try {
10676                    String name = r != null ? r.processName : null;
10677                    int pid = r != null ? r.pid : Binder.getCallingPid();
10678                    if (!mController.appCrashed(name, pid,
10679                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10680                        Slog.w(TAG, "Force-killing crashed app " + name
10681                                + " at watcher's request");
10682                        Process.killProcess(pid);
10683                        return;
10684                    }
10685                } catch (RemoteException e) {
10686                    mController = null;
10687                    Watchdog.getInstance().setActivityController(null);
10688                }
10689            }
10690
10691            final long origId = Binder.clearCallingIdentity();
10692
10693            // If this process is running instrumentation, finish it.
10694            if (r != null && r.instrumentationClass != null) {
10695                Slog.w(TAG, "Error in app " + r.processName
10696                      + " running instrumentation " + r.instrumentationClass + ":");
10697                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10698                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10699                Bundle info = new Bundle();
10700                info.putString("shortMsg", shortMsg);
10701                info.putString("longMsg", longMsg);
10702                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10703                Binder.restoreCallingIdentity(origId);
10704                return;
10705            }
10706
10707            // If we can't identify the process or it's already exceeded its crash quota,
10708            // quit right away without showing a crash dialog.
10709            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10710                Binder.restoreCallingIdentity(origId);
10711                return;
10712            }
10713
10714            Message msg = Message.obtain();
10715            msg.what = SHOW_ERROR_MSG;
10716            HashMap data = new HashMap();
10717            data.put("result", result);
10718            data.put("app", r);
10719            msg.obj = data;
10720            mHandler.sendMessage(msg);
10721
10722            Binder.restoreCallingIdentity(origId);
10723        }
10724
10725        int res = result.get();
10726
10727        Intent appErrorIntent = null;
10728        synchronized (this) {
10729            if (r != null && !r.isolated) {
10730                // XXX Can't keep track of crash time for isolated processes,
10731                // since they don't have a persistent identity.
10732                mProcessCrashTimes.put(r.info.processName, r.uid,
10733                        SystemClock.uptimeMillis());
10734            }
10735            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10736                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10737            }
10738        }
10739
10740        if (appErrorIntent != null) {
10741            try {
10742                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10743            } catch (ActivityNotFoundException e) {
10744                Slog.w(TAG, "bug report receiver dissappeared", e);
10745            }
10746        }
10747    }
10748
10749    Intent createAppErrorIntentLocked(ProcessRecord r,
10750            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10751        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10752        if (report == null) {
10753            return null;
10754        }
10755        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10756        result.setComponent(r.errorReportReceiver);
10757        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10758        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10759        return result;
10760    }
10761
10762    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10763            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10764        if (r.errorReportReceiver == null) {
10765            return null;
10766        }
10767
10768        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10769            return null;
10770        }
10771
10772        ApplicationErrorReport report = new ApplicationErrorReport();
10773        report.packageName = r.info.packageName;
10774        report.installerPackageName = r.errorReportReceiver.getPackageName();
10775        report.processName = r.processName;
10776        report.time = timeMillis;
10777        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10778
10779        if (r.crashing || r.forceCrashReport) {
10780            report.type = ApplicationErrorReport.TYPE_CRASH;
10781            report.crashInfo = crashInfo;
10782        } else if (r.notResponding) {
10783            report.type = ApplicationErrorReport.TYPE_ANR;
10784            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10785
10786            report.anrInfo.activity = r.notRespondingReport.tag;
10787            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10788            report.anrInfo.info = r.notRespondingReport.longMsg;
10789        }
10790
10791        return report;
10792    }
10793
10794    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10795        enforceNotIsolatedCaller("getProcessesInErrorState");
10796        // assume our apps are happy - lazy create the list
10797        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10798
10799        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10800                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10801        int userId = UserHandle.getUserId(Binder.getCallingUid());
10802
10803        synchronized (this) {
10804
10805            // iterate across all processes
10806            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10807                ProcessRecord app = mLruProcesses.get(i);
10808                if (!allUsers && app.userId != userId) {
10809                    continue;
10810                }
10811                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10812                    // This one's in trouble, so we'll generate a report for it
10813                    // crashes are higher priority (in case there's a crash *and* an anr)
10814                    ActivityManager.ProcessErrorStateInfo report = null;
10815                    if (app.crashing) {
10816                        report = app.crashingReport;
10817                    } else if (app.notResponding) {
10818                        report = app.notRespondingReport;
10819                    }
10820
10821                    if (report != null) {
10822                        if (errList == null) {
10823                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10824                        }
10825                        errList.add(report);
10826                    } else {
10827                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10828                                " crashing = " + app.crashing +
10829                                " notResponding = " + app.notResponding);
10830                    }
10831                }
10832            }
10833        }
10834
10835        return errList;
10836    }
10837
10838    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10839        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10840            if (currApp != null) {
10841                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10842            }
10843            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10844        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10845            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10846        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10847            if (currApp != null) {
10848                currApp.lru = 0;
10849            }
10850            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10851        } else if (adj >= ProcessList.SERVICE_ADJ) {
10852            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10853        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10854            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10855        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10856            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10857        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10858            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10859        } else {
10860            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10861        }
10862    }
10863
10864    private void fillInProcMemInfo(ProcessRecord app,
10865            ActivityManager.RunningAppProcessInfo outInfo) {
10866        outInfo.pid = app.pid;
10867        outInfo.uid = app.info.uid;
10868        if (mHeavyWeightProcess == app) {
10869            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10870        }
10871        if (app.persistent) {
10872            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10873        }
10874        if (app.activities.size() > 0) {
10875            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10876        }
10877        outInfo.lastTrimLevel = app.trimMemoryLevel;
10878        int adj = app.curAdj;
10879        outInfo.importance = oomAdjToImportance(adj, outInfo);
10880        outInfo.importanceReasonCode = app.adjTypeCode;
10881        outInfo.processState = app.curProcState;
10882    }
10883
10884    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10885        enforceNotIsolatedCaller("getRunningAppProcesses");
10886        // Lazy instantiation of list
10887        List<ActivityManager.RunningAppProcessInfo> runList = null;
10888        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10889                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10890        int userId = UserHandle.getUserId(Binder.getCallingUid());
10891        synchronized (this) {
10892            // Iterate across all processes
10893            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10894                ProcessRecord app = mLruProcesses.get(i);
10895                if (!allUsers && app.userId != userId) {
10896                    continue;
10897                }
10898                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10899                    // Generate process state info for running application
10900                    ActivityManager.RunningAppProcessInfo currApp =
10901                        new ActivityManager.RunningAppProcessInfo(app.processName,
10902                                app.pid, app.getPackageList());
10903                    fillInProcMemInfo(app, currApp);
10904                    if (app.adjSource instanceof ProcessRecord) {
10905                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10906                        currApp.importanceReasonImportance = oomAdjToImportance(
10907                                app.adjSourceOom, null);
10908                    } else if (app.adjSource instanceof ActivityRecord) {
10909                        ActivityRecord r = (ActivityRecord)app.adjSource;
10910                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10911                    }
10912                    if (app.adjTarget instanceof ComponentName) {
10913                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10914                    }
10915                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10916                    //        + " lru=" + currApp.lru);
10917                    if (runList == null) {
10918                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10919                    }
10920                    runList.add(currApp);
10921                }
10922            }
10923        }
10924        return runList;
10925    }
10926
10927    public List<ApplicationInfo> getRunningExternalApplications() {
10928        enforceNotIsolatedCaller("getRunningExternalApplications");
10929        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10930        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10931        if (runningApps != null && runningApps.size() > 0) {
10932            Set<String> extList = new HashSet<String>();
10933            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10934                if (app.pkgList != null) {
10935                    for (String pkg : app.pkgList) {
10936                        extList.add(pkg);
10937                    }
10938                }
10939            }
10940            IPackageManager pm = AppGlobals.getPackageManager();
10941            for (String pkg : extList) {
10942                try {
10943                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10944                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10945                        retList.add(info);
10946                    }
10947                } catch (RemoteException e) {
10948                }
10949            }
10950        }
10951        return retList;
10952    }
10953
10954    @Override
10955    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10956        enforceNotIsolatedCaller("getMyMemoryState");
10957        synchronized (this) {
10958            ProcessRecord proc;
10959            synchronized (mPidsSelfLocked) {
10960                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10961            }
10962            fillInProcMemInfo(proc, outInfo);
10963        }
10964    }
10965
10966    @Override
10967    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10968        if (checkCallingPermission(android.Manifest.permission.DUMP)
10969                != PackageManager.PERMISSION_GRANTED) {
10970            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10971                    + Binder.getCallingPid()
10972                    + ", uid=" + Binder.getCallingUid()
10973                    + " without permission "
10974                    + android.Manifest.permission.DUMP);
10975            return;
10976        }
10977
10978        boolean dumpAll = false;
10979        boolean dumpClient = false;
10980        String dumpPackage = null;
10981
10982        int opti = 0;
10983        while (opti < args.length) {
10984            String opt = args[opti];
10985            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10986                break;
10987            }
10988            opti++;
10989            if ("-a".equals(opt)) {
10990                dumpAll = true;
10991            } else if ("-c".equals(opt)) {
10992                dumpClient = true;
10993            } else if ("-h".equals(opt)) {
10994                pw.println("Activity manager dump options:");
10995                pw.println("  [-a] [-c] [-h] [cmd] ...");
10996                pw.println("  cmd may be one of:");
10997                pw.println("    a[ctivities]: activity stack state");
10998                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10999                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11000                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11001                pw.println("    o[om]: out of memory management");
11002                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11003                pw.println("    provider [COMP_SPEC]: provider client-side state");
11004                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11005                pw.println("    service [COMP_SPEC]: service client-side state");
11006                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11007                pw.println("    all: dump all activities");
11008                pw.println("    top: dump the top activity");
11009                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11010                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11011                pw.println("    a partial substring in a component name, a");
11012                pw.println("    hex object identifier.");
11013                pw.println("  -a: include all available server state.");
11014                pw.println("  -c: include client state.");
11015                return;
11016            } else {
11017                pw.println("Unknown argument: " + opt + "; use -h for help");
11018            }
11019        }
11020
11021        long origId = Binder.clearCallingIdentity();
11022        boolean more = false;
11023        // Is the caller requesting to dump a particular piece of data?
11024        if (opti < args.length) {
11025            String cmd = args[opti];
11026            opti++;
11027            if ("activities".equals(cmd) || "a".equals(cmd)) {
11028                synchronized (this) {
11029                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11030                }
11031            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11032                String[] newArgs;
11033                String name;
11034                if (opti >= args.length) {
11035                    name = null;
11036                    newArgs = EMPTY_STRING_ARRAY;
11037                } else {
11038                    name = args[opti];
11039                    opti++;
11040                    newArgs = new String[args.length - opti];
11041                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11042                            args.length - opti);
11043                }
11044                synchronized (this) {
11045                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11046                }
11047            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11048                String[] newArgs;
11049                String name;
11050                if (opti >= args.length) {
11051                    name = null;
11052                    newArgs = EMPTY_STRING_ARRAY;
11053                } else {
11054                    name = args[opti];
11055                    opti++;
11056                    newArgs = new String[args.length - opti];
11057                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11058                            args.length - opti);
11059                }
11060                synchronized (this) {
11061                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11062                }
11063            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11064                String[] newArgs;
11065                String name;
11066                if (opti >= args.length) {
11067                    name = null;
11068                    newArgs = EMPTY_STRING_ARRAY;
11069                } else {
11070                    name = args[opti];
11071                    opti++;
11072                    newArgs = new String[args.length - opti];
11073                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11074                            args.length - opti);
11075                }
11076                synchronized (this) {
11077                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11078                }
11079            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11080                synchronized (this) {
11081                    dumpOomLocked(fd, pw, args, opti, true);
11082                }
11083            } else if ("provider".equals(cmd)) {
11084                String[] newArgs;
11085                String name;
11086                if (opti >= args.length) {
11087                    name = null;
11088                    newArgs = EMPTY_STRING_ARRAY;
11089                } else {
11090                    name = args[opti];
11091                    opti++;
11092                    newArgs = new String[args.length - opti];
11093                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11094                }
11095                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11096                    pw.println("No providers match: " + name);
11097                    pw.println("Use -h for help.");
11098                }
11099            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11100                synchronized (this) {
11101                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11102                }
11103            } else if ("service".equals(cmd)) {
11104                String[] newArgs;
11105                String name;
11106                if (opti >= args.length) {
11107                    name = null;
11108                    newArgs = EMPTY_STRING_ARRAY;
11109                } else {
11110                    name = args[opti];
11111                    opti++;
11112                    newArgs = new String[args.length - opti];
11113                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11114                            args.length - opti);
11115                }
11116                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11117                    pw.println("No services match: " + name);
11118                    pw.println("Use -h for help.");
11119                }
11120            } else if ("package".equals(cmd)) {
11121                String[] newArgs;
11122                if (opti >= args.length) {
11123                    pw.println("package: no package name specified");
11124                    pw.println("Use -h for help.");
11125                } else {
11126                    dumpPackage = args[opti];
11127                    opti++;
11128                    newArgs = new String[args.length - opti];
11129                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11130                            args.length - opti);
11131                    args = newArgs;
11132                    opti = 0;
11133                    more = true;
11134                }
11135            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11136                synchronized (this) {
11137                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11138                }
11139            } else {
11140                // Dumping a single activity?
11141                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11142                    pw.println("Bad activity command, or no activities match: " + cmd);
11143                    pw.println("Use -h for help.");
11144                }
11145            }
11146            if (!more) {
11147                Binder.restoreCallingIdentity(origId);
11148                return;
11149            }
11150        }
11151
11152        // No piece of data specified, dump everything.
11153        synchronized (this) {
11154            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11155            pw.println();
11156            if (dumpAll) {
11157                pw.println("-------------------------------------------------------------------------------");
11158            }
11159            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11160            pw.println();
11161            if (dumpAll) {
11162                pw.println("-------------------------------------------------------------------------------");
11163            }
11164            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11165            pw.println();
11166            if (dumpAll) {
11167                pw.println("-------------------------------------------------------------------------------");
11168            }
11169            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11170            pw.println();
11171            if (dumpAll) {
11172                pw.println("-------------------------------------------------------------------------------");
11173            }
11174            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11175            pw.println();
11176            if (dumpAll) {
11177                pw.println("-------------------------------------------------------------------------------");
11178            }
11179            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11180        }
11181        Binder.restoreCallingIdentity(origId);
11182    }
11183
11184    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11185            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11186        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11187
11188        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11189                dumpPackage);
11190        boolean needSep = printedAnything;
11191
11192        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11193                dumpPackage, needSep, "  mFocusedActivity: ");
11194        if (printed) {
11195            printedAnything = true;
11196            needSep = false;
11197        }
11198
11199        if (dumpPackage == null) {
11200            if (needSep) {
11201                pw.println();
11202            }
11203            needSep = true;
11204            printedAnything = true;
11205            mStackSupervisor.dump(pw, "  ");
11206        }
11207
11208        if (mRecentTasks.size() > 0) {
11209            boolean printedHeader = false;
11210
11211            final int N = mRecentTasks.size();
11212            for (int i=0; i<N; i++) {
11213                TaskRecord tr = mRecentTasks.get(i);
11214                if (dumpPackage != null) {
11215                    if (tr.realActivity == null ||
11216                            !dumpPackage.equals(tr.realActivity)) {
11217                        continue;
11218                    }
11219                }
11220                if (!printedHeader) {
11221                    if (needSep) {
11222                        pw.println();
11223                    }
11224                    pw.println("  Recent tasks:");
11225                    printedHeader = true;
11226                    printedAnything = true;
11227                }
11228                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11229                        pw.println(tr);
11230                if (dumpAll) {
11231                    mRecentTasks.get(i).dump(pw, "    ");
11232                }
11233            }
11234        }
11235
11236        if (!printedAnything) {
11237            pw.println("  (nothing)");
11238        }
11239    }
11240
11241    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11242            int opti, boolean dumpAll, String dumpPackage) {
11243        boolean needSep = false;
11244        boolean printedAnything = false;
11245        int numPers = 0;
11246
11247        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11248
11249        if (dumpAll) {
11250            final int NP = mProcessNames.getMap().size();
11251            for (int ip=0; ip<NP; ip++) {
11252                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11253                final int NA = procs.size();
11254                for (int ia=0; ia<NA; ia++) {
11255                    ProcessRecord r = procs.valueAt(ia);
11256                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11257                        continue;
11258                    }
11259                    if (!needSep) {
11260                        pw.println("  All known processes:");
11261                        needSep = true;
11262                        printedAnything = true;
11263                    }
11264                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11265                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11266                        pw.print(" "); pw.println(r);
11267                    r.dump(pw, "    ");
11268                    if (r.persistent) {
11269                        numPers++;
11270                    }
11271                }
11272            }
11273        }
11274
11275        if (mIsolatedProcesses.size() > 0) {
11276            boolean printed = false;
11277            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11278                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11279                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11280                    continue;
11281                }
11282                if (!printed) {
11283                    if (needSep) {
11284                        pw.println();
11285                    }
11286                    pw.println("  Isolated process list (sorted by uid):");
11287                    printedAnything = true;
11288                    printed = true;
11289                    needSep = true;
11290                }
11291                pw.println(String.format("%sIsolated #%2d: %s",
11292                        "    ", i, r.toString()));
11293            }
11294        }
11295
11296        if (mLruProcesses.size() > 0) {
11297            if (needSep) {
11298                pw.println();
11299            }
11300            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11301                    pw.print(" total, non-act at ");
11302                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11303                    pw.print(", non-svc at ");
11304                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11305                    pw.println("):");
11306            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11307            needSep = true;
11308            printedAnything = true;
11309        }
11310
11311        if (dumpAll || dumpPackage != null) {
11312            synchronized (mPidsSelfLocked) {
11313                boolean printed = false;
11314                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11315                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11316                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11317                        continue;
11318                    }
11319                    if (!printed) {
11320                        if (needSep) pw.println();
11321                        needSep = true;
11322                        pw.println("  PID mappings:");
11323                        printed = true;
11324                        printedAnything = true;
11325                    }
11326                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11327                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11328                }
11329            }
11330        }
11331
11332        if (mForegroundProcesses.size() > 0) {
11333            synchronized (mPidsSelfLocked) {
11334                boolean printed = false;
11335                for (int i=0; i<mForegroundProcesses.size(); i++) {
11336                    ProcessRecord r = mPidsSelfLocked.get(
11337                            mForegroundProcesses.valueAt(i).pid);
11338                    if (dumpPackage != null && (r == null
11339                            || !r.pkgList.containsKey(dumpPackage))) {
11340                        continue;
11341                    }
11342                    if (!printed) {
11343                        if (needSep) pw.println();
11344                        needSep = true;
11345                        pw.println("  Foreground Processes:");
11346                        printed = true;
11347                        printedAnything = true;
11348                    }
11349                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11350                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11351                }
11352            }
11353        }
11354
11355        if (mPersistentStartingProcesses.size() > 0) {
11356            if (needSep) pw.println();
11357            needSep = true;
11358            printedAnything = true;
11359            pw.println("  Persisent processes that are starting:");
11360            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11361                    "Starting Norm", "Restarting PERS", dumpPackage);
11362        }
11363
11364        if (mRemovedProcesses.size() > 0) {
11365            if (needSep) pw.println();
11366            needSep = true;
11367            printedAnything = true;
11368            pw.println("  Processes that are being removed:");
11369            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11370                    "Removed Norm", "Removed PERS", dumpPackage);
11371        }
11372
11373        if (mProcessesOnHold.size() > 0) {
11374            if (needSep) pw.println();
11375            needSep = true;
11376            printedAnything = true;
11377            pw.println("  Processes that are on old until the system is ready:");
11378            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11379                    "OnHold Norm", "OnHold PERS", dumpPackage);
11380        }
11381
11382        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11383
11384        if (mProcessCrashTimes.getMap().size() > 0) {
11385            boolean printed = false;
11386            long now = SystemClock.uptimeMillis();
11387            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11388            final int NP = pmap.size();
11389            for (int ip=0; ip<NP; ip++) {
11390                String pname = pmap.keyAt(ip);
11391                SparseArray<Long> uids = pmap.valueAt(ip);
11392                final int N = uids.size();
11393                for (int i=0; i<N; i++) {
11394                    int puid = uids.keyAt(i);
11395                    ProcessRecord r = mProcessNames.get(pname, puid);
11396                    if (dumpPackage != null && (r == null
11397                            || !r.pkgList.containsKey(dumpPackage))) {
11398                        continue;
11399                    }
11400                    if (!printed) {
11401                        if (needSep) pw.println();
11402                        needSep = true;
11403                        pw.println("  Time since processes crashed:");
11404                        printed = true;
11405                        printedAnything = true;
11406                    }
11407                    pw.print("    Process "); pw.print(pname);
11408                            pw.print(" uid "); pw.print(puid);
11409                            pw.print(": last crashed ");
11410                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11411                            pw.println(" ago");
11412                }
11413            }
11414        }
11415
11416        if (mBadProcesses.getMap().size() > 0) {
11417            boolean printed = false;
11418            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11419            final int NP = pmap.size();
11420            for (int ip=0; ip<NP; ip++) {
11421                String pname = pmap.keyAt(ip);
11422                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11423                final int N = uids.size();
11424                for (int i=0; i<N; i++) {
11425                    int puid = uids.keyAt(i);
11426                    ProcessRecord r = mProcessNames.get(pname, puid);
11427                    if (dumpPackage != null && (r == null
11428                            || !r.pkgList.containsKey(dumpPackage))) {
11429                        continue;
11430                    }
11431                    if (!printed) {
11432                        if (needSep) pw.println();
11433                        needSep = true;
11434                        pw.println("  Bad processes:");
11435                        printedAnything = true;
11436                    }
11437                    BadProcessInfo info = uids.valueAt(i);
11438                    pw.print("    Bad process "); pw.print(pname);
11439                            pw.print(" uid "); pw.print(puid);
11440                            pw.print(": crashed at time "); pw.println(info.time);
11441                    if (info.shortMsg != null) {
11442                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11443                    }
11444                    if (info.longMsg != null) {
11445                        pw.print("      Long msg: "); pw.println(info.longMsg);
11446                    }
11447                    if (info.stack != null) {
11448                        pw.println("      Stack:");
11449                        int lastPos = 0;
11450                        for (int pos=0; pos<info.stack.length(); pos++) {
11451                            if (info.stack.charAt(pos) == '\n') {
11452                                pw.print("        ");
11453                                pw.write(info.stack, lastPos, pos-lastPos);
11454                                pw.println();
11455                                lastPos = pos+1;
11456                            }
11457                        }
11458                        if (lastPos < info.stack.length()) {
11459                            pw.print("        ");
11460                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11461                            pw.println();
11462                        }
11463                    }
11464                }
11465            }
11466        }
11467
11468        if (dumpPackage == null) {
11469            pw.println();
11470            needSep = false;
11471            pw.println("  mStartedUsers:");
11472            for (int i=0; i<mStartedUsers.size(); i++) {
11473                UserStartedState uss = mStartedUsers.valueAt(i);
11474                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11475                        pw.print(": "); uss.dump("", pw);
11476            }
11477            pw.print("  mStartedUserArray: [");
11478            for (int i=0; i<mStartedUserArray.length; i++) {
11479                if (i > 0) pw.print(", ");
11480                pw.print(mStartedUserArray[i]);
11481            }
11482            pw.println("]");
11483            pw.print("  mUserLru: [");
11484            for (int i=0; i<mUserLru.size(); i++) {
11485                if (i > 0) pw.print(", ");
11486                pw.print(mUserLru.get(i));
11487            }
11488            pw.println("]");
11489            if (dumpAll) {
11490                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11491            }
11492        }
11493        if (mHomeProcess != null && (dumpPackage == null
11494                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11495            if (needSep) {
11496                pw.println();
11497                needSep = false;
11498            }
11499            pw.println("  mHomeProcess: " + mHomeProcess);
11500        }
11501        if (mPreviousProcess != null && (dumpPackage == null
11502                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11503            if (needSep) {
11504                pw.println();
11505                needSep = false;
11506            }
11507            pw.println("  mPreviousProcess: " + mPreviousProcess);
11508        }
11509        if (dumpAll) {
11510            StringBuilder sb = new StringBuilder(128);
11511            sb.append("  mPreviousProcessVisibleTime: ");
11512            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11513            pw.println(sb);
11514        }
11515        if (mHeavyWeightProcess != null && (dumpPackage == null
11516                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11517            if (needSep) {
11518                pw.println();
11519                needSep = false;
11520            }
11521            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11522        }
11523        if (dumpPackage == null) {
11524            pw.println("  mConfiguration: " + mConfiguration);
11525        }
11526        if (dumpAll) {
11527            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11528            if (mCompatModePackages.getPackages().size() > 0) {
11529                boolean printed = false;
11530                for (Map.Entry<String, Integer> entry
11531                        : mCompatModePackages.getPackages().entrySet()) {
11532                    String pkg = entry.getKey();
11533                    int mode = entry.getValue();
11534                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11535                        continue;
11536                    }
11537                    if (!printed) {
11538                        pw.println("  mScreenCompatPackages:");
11539                        printed = true;
11540                    }
11541                    pw.print("    "); pw.print(pkg); pw.print(": ");
11542                            pw.print(mode); pw.println();
11543                }
11544            }
11545        }
11546        if (dumpPackage == null) {
11547            if (mSleeping || mWentToSleep || mLockScreenShown) {
11548                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11549                        + " mLockScreenShown " + mLockScreenShown);
11550            }
11551            if (mShuttingDown || mRunningVoice) {
11552                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11553            }
11554        }
11555        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11556                || mOrigWaitForDebugger) {
11557            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11558                    || dumpPackage.equals(mOrigDebugApp)) {
11559                if (needSep) {
11560                    pw.println();
11561                    needSep = false;
11562                }
11563                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11564                        + " mDebugTransient=" + mDebugTransient
11565                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11566            }
11567        }
11568        if (mOpenGlTraceApp != null) {
11569            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11570                if (needSep) {
11571                    pw.println();
11572                    needSep = false;
11573                }
11574                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11575            }
11576        }
11577        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11578                || mProfileFd != null) {
11579            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11580                if (needSep) {
11581                    pw.println();
11582                    needSep = false;
11583                }
11584                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11585                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11586                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11587                        + mAutoStopProfiler);
11588            }
11589        }
11590        if (dumpPackage == null) {
11591            if (mAlwaysFinishActivities || mController != null) {
11592                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11593                        + " mController=" + mController);
11594            }
11595            if (dumpAll) {
11596                pw.println("  Total persistent processes: " + numPers);
11597                pw.println("  mProcessesReady=" + mProcessesReady
11598                        + " mSystemReady=" + mSystemReady);
11599                pw.println("  mBooting=" + mBooting
11600                        + " mBooted=" + mBooted
11601                        + " mFactoryTest=" + mFactoryTest);
11602                pw.print("  mLastPowerCheckRealtime=");
11603                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11604                        pw.println("");
11605                pw.print("  mLastPowerCheckUptime=");
11606                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11607                        pw.println("");
11608                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11609                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11610                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11611                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11612                        + " (" + mLruProcesses.size() + " total)"
11613                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11614                        + " mNumServiceProcs=" + mNumServiceProcs
11615                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11616                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11617                        + " mLastMemoryLevel" + mLastMemoryLevel
11618                        + " mLastNumProcesses" + mLastNumProcesses);
11619                long now = SystemClock.uptimeMillis();
11620                pw.print("  mLastIdleTime=");
11621                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11622                        pw.print(" mLowRamSinceLastIdle=");
11623                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11624                        pw.println();
11625            }
11626        }
11627
11628        if (!printedAnything) {
11629            pw.println("  (nothing)");
11630        }
11631    }
11632
11633    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11634            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11635        if (mProcessesToGc.size() > 0) {
11636            boolean printed = false;
11637            long now = SystemClock.uptimeMillis();
11638            for (int i=0; i<mProcessesToGc.size(); i++) {
11639                ProcessRecord proc = mProcessesToGc.get(i);
11640                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11641                    continue;
11642                }
11643                if (!printed) {
11644                    if (needSep) pw.println();
11645                    needSep = true;
11646                    pw.println("  Processes that are waiting to GC:");
11647                    printed = true;
11648                }
11649                pw.print("    Process "); pw.println(proc);
11650                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11651                        pw.print(", last gced=");
11652                        pw.print(now-proc.lastRequestedGc);
11653                        pw.print(" ms ago, last lowMem=");
11654                        pw.print(now-proc.lastLowMemory);
11655                        pw.println(" ms ago");
11656
11657            }
11658        }
11659        return needSep;
11660    }
11661
11662    void printOomLevel(PrintWriter pw, String name, int adj) {
11663        pw.print("    ");
11664        if (adj >= 0) {
11665            pw.print(' ');
11666            if (adj < 10) pw.print(' ');
11667        } else {
11668            if (adj > -10) pw.print(' ');
11669        }
11670        pw.print(adj);
11671        pw.print(": ");
11672        pw.print(name);
11673        pw.print(" (");
11674        pw.print(mProcessList.getMemLevel(adj)/1024);
11675        pw.println(" kB)");
11676    }
11677
11678    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11679            int opti, boolean dumpAll) {
11680        boolean needSep = false;
11681
11682        if (mLruProcesses.size() > 0) {
11683            if (needSep) pw.println();
11684            needSep = true;
11685            pw.println("  OOM levels:");
11686            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11687            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11688            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11689            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11690            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11691            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11692            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11693            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11694            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11695            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11696            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11697            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11698            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11699
11700            if (needSep) pw.println();
11701            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11702                    pw.print(" total, non-act at ");
11703                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11704                    pw.print(", non-svc at ");
11705                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11706                    pw.println("):");
11707            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11708            needSep = true;
11709        }
11710
11711        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11712
11713        pw.println();
11714        pw.println("  mHomeProcess: " + mHomeProcess);
11715        pw.println("  mPreviousProcess: " + mPreviousProcess);
11716        if (mHeavyWeightProcess != null) {
11717            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11718        }
11719
11720        return true;
11721    }
11722
11723    /**
11724     * There are three ways to call this:
11725     *  - no provider specified: dump all the providers
11726     *  - a flattened component name that matched an existing provider was specified as the
11727     *    first arg: dump that one provider
11728     *  - the first arg isn't the flattened component name of an existing provider:
11729     *    dump all providers whose component contains the first arg as a substring
11730     */
11731    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11732            int opti, boolean dumpAll) {
11733        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11734    }
11735
11736    static class ItemMatcher {
11737        ArrayList<ComponentName> components;
11738        ArrayList<String> strings;
11739        ArrayList<Integer> objects;
11740        boolean all;
11741
11742        ItemMatcher() {
11743            all = true;
11744        }
11745
11746        void build(String name) {
11747            ComponentName componentName = ComponentName.unflattenFromString(name);
11748            if (componentName != null) {
11749                if (components == null) {
11750                    components = new ArrayList<ComponentName>();
11751                }
11752                components.add(componentName);
11753                all = false;
11754            } else {
11755                int objectId = 0;
11756                // Not a '/' separated full component name; maybe an object ID?
11757                try {
11758                    objectId = Integer.parseInt(name, 16);
11759                    if (objects == null) {
11760                        objects = new ArrayList<Integer>();
11761                    }
11762                    objects.add(objectId);
11763                    all = false;
11764                } catch (RuntimeException e) {
11765                    // Not an integer; just do string match.
11766                    if (strings == null) {
11767                        strings = new ArrayList<String>();
11768                    }
11769                    strings.add(name);
11770                    all = false;
11771                }
11772            }
11773        }
11774
11775        int build(String[] args, int opti) {
11776            for (; opti<args.length; opti++) {
11777                String name = args[opti];
11778                if ("--".equals(name)) {
11779                    return opti+1;
11780                }
11781                build(name);
11782            }
11783            return opti;
11784        }
11785
11786        boolean match(Object object, ComponentName comp) {
11787            if (all) {
11788                return true;
11789            }
11790            if (components != null) {
11791                for (int i=0; i<components.size(); i++) {
11792                    if (components.get(i).equals(comp)) {
11793                        return true;
11794                    }
11795                }
11796            }
11797            if (objects != null) {
11798                for (int i=0; i<objects.size(); i++) {
11799                    if (System.identityHashCode(object) == objects.get(i)) {
11800                        return true;
11801                    }
11802                }
11803            }
11804            if (strings != null) {
11805                String flat = comp.flattenToString();
11806                for (int i=0; i<strings.size(); i++) {
11807                    if (flat.contains(strings.get(i))) {
11808                        return true;
11809                    }
11810                }
11811            }
11812            return false;
11813        }
11814    }
11815
11816    /**
11817     * There are three things that cmd can be:
11818     *  - a flattened component name that matches an existing activity
11819     *  - the cmd arg isn't the flattened component name of an existing activity:
11820     *    dump all activity whose component contains the cmd as a substring
11821     *  - A hex number of the ActivityRecord object instance.
11822     */
11823    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11824            int opti, boolean dumpAll) {
11825        ArrayList<ActivityRecord> activities;
11826
11827        synchronized (this) {
11828            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11829        }
11830
11831        if (activities.size() <= 0) {
11832            return false;
11833        }
11834
11835        String[] newArgs = new String[args.length - opti];
11836        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11837
11838        TaskRecord lastTask = null;
11839        boolean needSep = false;
11840        for (int i=activities.size()-1; i>=0; i--) {
11841            ActivityRecord r = activities.get(i);
11842            if (needSep) {
11843                pw.println();
11844            }
11845            needSep = true;
11846            synchronized (this) {
11847                if (lastTask != r.task) {
11848                    lastTask = r.task;
11849                    pw.print("TASK "); pw.print(lastTask.affinity);
11850                            pw.print(" id="); pw.println(lastTask.taskId);
11851                    if (dumpAll) {
11852                        lastTask.dump(pw, "  ");
11853                    }
11854                }
11855            }
11856            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11857        }
11858        return true;
11859    }
11860
11861    /**
11862     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11863     * there is a thread associated with the activity.
11864     */
11865    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11866            final ActivityRecord r, String[] args, boolean dumpAll) {
11867        String innerPrefix = prefix + "  ";
11868        synchronized (this) {
11869            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11870                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11871                    pw.print(" pid=");
11872                    if (r.app != null) pw.println(r.app.pid);
11873                    else pw.println("(not running)");
11874            if (dumpAll) {
11875                r.dump(pw, innerPrefix);
11876            }
11877        }
11878        if (r.app != null && r.app.thread != null) {
11879            // flush anything that is already in the PrintWriter since the thread is going
11880            // to write to the file descriptor directly
11881            pw.flush();
11882            try {
11883                TransferPipe tp = new TransferPipe();
11884                try {
11885                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11886                            r.appToken, innerPrefix, args);
11887                    tp.go(fd);
11888                } finally {
11889                    tp.kill();
11890                }
11891            } catch (IOException e) {
11892                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11893            } catch (RemoteException e) {
11894                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11895            }
11896        }
11897    }
11898
11899    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11900            int opti, boolean dumpAll, String dumpPackage) {
11901        boolean needSep = false;
11902        boolean onlyHistory = false;
11903        boolean printedAnything = false;
11904
11905        if ("history".equals(dumpPackage)) {
11906            if (opti < args.length && "-s".equals(args[opti])) {
11907                dumpAll = false;
11908            }
11909            onlyHistory = true;
11910            dumpPackage = null;
11911        }
11912
11913        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11914        if (!onlyHistory && dumpAll) {
11915            if (mRegisteredReceivers.size() > 0) {
11916                boolean printed = false;
11917                Iterator it = mRegisteredReceivers.values().iterator();
11918                while (it.hasNext()) {
11919                    ReceiverList r = (ReceiverList)it.next();
11920                    if (dumpPackage != null && (r.app == null ||
11921                            !dumpPackage.equals(r.app.info.packageName))) {
11922                        continue;
11923                    }
11924                    if (!printed) {
11925                        pw.println("  Registered Receivers:");
11926                        needSep = true;
11927                        printed = true;
11928                        printedAnything = true;
11929                    }
11930                    pw.print("  * "); pw.println(r);
11931                    r.dump(pw, "    ");
11932                }
11933            }
11934
11935            if (mReceiverResolver.dump(pw, needSep ?
11936                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11937                    "    ", dumpPackage, false)) {
11938                needSep = true;
11939                printedAnything = true;
11940            }
11941        }
11942
11943        for (BroadcastQueue q : mBroadcastQueues) {
11944            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11945            printedAnything |= needSep;
11946        }
11947
11948        needSep = true;
11949
11950        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11951            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11952                if (needSep) {
11953                    pw.println();
11954                }
11955                needSep = true;
11956                printedAnything = true;
11957                pw.print("  Sticky broadcasts for user ");
11958                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11959                StringBuilder sb = new StringBuilder(128);
11960                for (Map.Entry<String, ArrayList<Intent>> ent
11961                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11962                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11963                    if (dumpAll) {
11964                        pw.println(":");
11965                        ArrayList<Intent> intents = ent.getValue();
11966                        final int N = intents.size();
11967                        for (int i=0; i<N; i++) {
11968                            sb.setLength(0);
11969                            sb.append("    Intent: ");
11970                            intents.get(i).toShortString(sb, false, true, false, false);
11971                            pw.println(sb.toString());
11972                            Bundle bundle = intents.get(i).getExtras();
11973                            if (bundle != null) {
11974                                pw.print("      ");
11975                                pw.println(bundle.toString());
11976                            }
11977                        }
11978                    } else {
11979                        pw.println("");
11980                    }
11981                }
11982            }
11983        }
11984
11985        if (!onlyHistory && dumpAll) {
11986            pw.println();
11987            for (BroadcastQueue queue : mBroadcastQueues) {
11988                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11989                        + queue.mBroadcastsScheduled);
11990            }
11991            pw.println("  mHandler:");
11992            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11993            needSep = true;
11994            printedAnything = true;
11995        }
11996
11997        if (!printedAnything) {
11998            pw.println("  (nothing)");
11999        }
12000    }
12001
12002    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12003            int opti, boolean dumpAll, String dumpPackage) {
12004        boolean needSep;
12005        boolean printedAnything = false;
12006
12007        ItemMatcher matcher = new ItemMatcher();
12008        matcher.build(args, opti);
12009
12010        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12011
12012        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12013        printedAnything |= needSep;
12014
12015        if (mLaunchingProviders.size() > 0) {
12016            boolean printed = false;
12017            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12018                ContentProviderRecord r = mLaunchingProviders.get(i);
12019                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12020                    continue;
12021                }
12022                if (!printed) {
12023                    if (needSep) pw.println();
12024                    needSep = true;
12025                    pw.println("  Launching content providers:");
12026                    printed = true;
12027                    printedAnything = true;
12028                }
12029                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12030                        pw.println(r);
12031            }
12032        }
12033
12034        if (mGrantedUriPermissions.size() > 0) {
12035            boolean printed = false;
12036            int dumpUid = -2;
12037            if (dumpPackage != null) {
12038                try {
12039                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12040                } catch (NameNotFoundException e) {
12041                    dumpUid = -1;
12042                }
12043            }
12044            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12045                int uid = mGrantedUriPermissions.keyAt(i);
12046                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12047                    continue;
12048                }
12049                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12050                if (!printed) {
12051                    if (needSep) pw.println();
12052                    needSep = true;
12053                    pw.println("  Granted Uri Permissions:");
12054                    printed = true;
12055                    printedAnything = true;
12056                }
12057                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12058                for (UriPermission perm : perms.values()) {
12059                    pw.print("    "); pw.println(perm);
12060                    if (dumpAll) {
12061                        perm.dump(pw, "      ");
12062                    }
12063                }
12064            }
12065        }
12066
12067        if (!printedAnything) {
12068            pw.println("  (nothing)");
12069        }
12070    }
12071
12072    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12073            int opti, boolean dumpAll, String dumpPackage) {
12074        boolean printed = false;
12075
12076        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12077
12078        if (mIntentSenderRecords.size() > 0) {
12079            Iterator<WeakReference<PendingIntentRecord>> it
12080                    = mIntentSenderRecords.values().iterator();
12081            while (it.hasNext()) {
12082                WeakReference<PendingIntentRecord> ref = it.next();
12083                PendingIntentRecord rec = ref != null ? ref.get(): null;
12084                if (dumpPackage != null && (rec == null
12085                        || !dumpPackage.equals(rec.key.packageName))) {
12086                    continue;
12087                }
12088                printed = true;
12089                if (rec != null) {
12090                    pw.print("  * "); pw.println(rec);
12091                    if (dumpAll) {
12092                        rec.dump(pw, "    ");
12093                    }
12094                } else {
12095                    pw.print("  * "); pw.println(ref);
12096                }
12097            }
12098        }
12099
12100        if (!printed) {
12101            pw.println("  (nothing)");
12102        }
12103    }
12104
12105    private static final int dumpProcessList(PrintWriter pw,
12106            ActivityManagerService service, List list,
12107            String prefix, String normalLabel, String persistentLabel,
12108            String dumpPackage) {
12109        int numPers = 0;
12110        final int N = list.size()-1;
12111        for (int i=N; i>=0; i--) {
12112            ProcessRecord r = (ProcessRecord)list.get(i);
12113            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12114                continue;
12115            }
12116            pw.println(String.format("%s%s #%2d: %s",
12117                    prefix, (r.persistent ? persistentLabel : normalLabel),
12118                    i, r.toString()));
12119            if (r.persistent) {
12120                numPers++;
12121            }
12122        }
12123        return numPers;
12124    }
12125
12126    private static final boolean dumpProcessOomList(PrintWriter pw,
12127            ActivityManagerService service, List<ProcessRecord> origList,
12128            String prefix, String normalLabel, String persistentLabel,
12129            boolean inclDetails, String dumpPackage) {
12130
12131        ArrayList<Pair<ProcessRecord, Integer>> list
12132                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12133        for (int i=0; i<origList.size(); i++) {
12134            ProcessRecord r = origList.get(i);
12135            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12136                continue;
12137            }
12138            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12139        }
12140
12141        if (list.size() <= 0) {
12142            return false;
12143        }
12144
12145        Comparator<Pair<ProcessRecord, Integer>> comparator
12146                = new Comparator<Pair<ProcessRecord, Integer>>() {
12147            @Override
12148            public int compare(Pair<ProcessRecord, Integer> object1,
12149                    Pair<ProcessRecord, Integer> object2) {
12150                if (object1.first.setAdj != object2.first.setAdj) {
12151                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12152                }
12153                if (object1.second.intValue() != object2.second.intValue()) {
12154                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12155                }
12156                return 0;
12157            }
12158        };
12159
12160        Collections.sort(list, comparator);
12161
12162        final long curRealtime = SystemClock.elapsedRealtime();
12163        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12164        final long curUptime = SystemClock.uptimeMillis();
12165        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12166
12167        for (int i=list.size()-1; i>=0; i--) {
12168            ProcessRecord r = list.get(i).first;
12169            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12170            char schedGroup;
12171            switch (r.setSchedGroup) {
12172                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12173                    schedGroup = 'B';
12174                    break;
12175                case Process.THREAD_GROUP_DEFAULT:
12176                    schedGroup = 'F';
12177                    break;
12178                default:
12179                    schedGroup = '?';
12180                    break;
12181            }
12182            char foreground;
12183            if (r.foregroundActivities) {
12184                foreground = 'A';
12185            } else if (r.foregroundServices) {
12186                foreground = 'S';
12187            } else {
12188                foreground = ' ';
12189            }
12190            String procState = ProcessList.makeProcStateString(r.curProcState);
12191            pw.print(prefix);
12192            pw.print(r.persistent ? persistentLabel : normalLabel);
12193            pw.print(" #");
12194            int num = (origList.size()-1)-list.get(i).second;
12195            if (num < 10) pw.print(' ');
12196            pw.print(num);
12197            pw.print(": ");
12198            pw.print(oomAdj);
12199            pw.print(' ');
12200            pw.print(schedGroup);
12201            pw.print('/');
12202            pw.print(foreground);
12203            pw.print('/');
12204            pw.print(procState);
12205            pw.print(" trm:");
12206            if (r.trimMemoryLevel < 10) pw.print(' ');
12207            pw.print(r.trimMemoryLevel);
12208            pw.print(' ');
12209            pw.print(r.toShortString());
12210            pw.print(" (");
12211            pw.print(r.adjType);
12212            pw.println(')');
12213            if (r.adjSource != null || r.adjTarget != null) {
12214                pw.print(prefix);
12215                pw.print("    ");
12216                if (r.adjTarget instanceof ComponentName) {
12217                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12218                } else if (r.adjTarget != null) {
12219                    pw.print(r.adjTarget.toString());
12220                } else {
12221                    pw.print("{null}");
12222                }
12223                pw.print("<=");
12224                if (r.adjSource instanceof ProcessRecord) {
12225                    pw.print("Proc{");
12226                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12227                    pw.println("}");
12228                } else if (r.adjSource != null) {
12229                    pw.println(r.adjSource.toString());
12230                } else {
12231                    pw.println("{null}");
12232                }
12233            }
12234            if (inclDetails) {
12235                pw.print(prefix);
12236                pw.print("    ");
12237                pw.print("oom: max="); pw.print(r.maxAdj);
12238                pw.print(" curRaw="); pw.print(r.curRawAdj);
12239                pw.print(" setRaw="); pw.print(r.setRawAdj);
12240                pw.print(" cur="); pw.print(r.curAdj);
12241                pw.print(" set="); pw.println(r.setAdj);
12242                pw.print(prefix);
12243                pw.print("    ");
12244                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12245                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12246                pw.print(" lastPss="); pw.print(r.lastPss);
12247                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12248                pw.print(prefix);
12249                pw.print("    ");
12250                pw.print("keeping="); pw.print(r.keeping);
12251                pw.print(" cached="); pw.print(r.cached);
12252                pw.print(" empty="); pw.print(r.empty);
12253                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12254
12255                if (!r.keeping) {
12256                    if (r.lastWakeTime != 0) {
12257                        long wtime;
12258                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12259                        synchronized (stats) {
12260                            wtime = stats.getProcessWakeTime(r.info.uid,
12261                                    r.pid, curRealtime);
12262                        }
12263                        long timeUsed = wtime - r.lastWakeTime;
12264                        pw.print(prefix);
12265                        pw.print("    ");
12266                        pw.print("keep awake over ");
12267                        TimeUtils.formatDuration(realtimeSince, pw);
12268                        pw.print(" used ");
12269                        TimeUtils.formatDuration(timeUsed, pw);
12270                        pw.print(" (");
12271                        pw.print((timeUsed*100)/realtimeSince);
12272                        pw.println("%)");
12273                    }
12274                    if (r.lastCpuTime != 0) {
12275                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12276                        pw.print(prefix);
12277                        pw.print("    ");
12278                        pw.print("run cpu over ");
12279                        TimeUtils.formatDuration(uptimeSince, pw);
12280                        pw.print(" used ");
12281                        TimeUtils.formatDuration(timeUsed, pw);
12282                        pw.print(" (");
12283                        pw.print((timeUsed*100)/uptimeSince);
12284                        pw.println("%)");
12285                    }
12286                }
12287            }
12288        }
12289        return true;
12290    }
12291
12292    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12293        ArrayList<ProcessRecord> procs;
12294        synchronized (this) {
12295            if (args != null && args.length > start
12296                    && args[start].charAt(0) != '-') {
12297                procs = new ArrayList<ProcessRecord>();
12298                int pid = -1;
12299                try {
12300                    pid = Integer.parseInt(args[start]);
12301                } catch (NumberFormatException e) {
12302                }
12303                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12304                    ProcessRecord proc = mLruProcesses.get(i);
12305                    if (proc.pid == pid) {
12306                        procs.add(proc);
12307                    } else if (proc.processName.equals(args[start])) {
12308                        procs.add(proc);
12309                    }
12310                }
12311                if (procs.size() <= 0) {
12312                    return null;
12313                }
12314            } else {
12315                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12316            }
12317        }
12318        return procs;
12319    }
12320
12321    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12322            PrintWriter pw, String[] args) {
12323        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12324        if (procs == null) {
12325            pw.println("No process found for: " + args[0]);
12326            return;
12327        }
12328
12329        long uptime = SystemClock.uptimeMillis();
12330        long realtime = SystemClock.elapsedRealtime();
12331        pw.println("Applications Graphics Acceleration Info:");
12332        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12333
12334        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12335            ProcessRecord r = procs.get(i);
12336            if (r.thread != null) {
12337                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12338                pw.flush();
12339                try {
12340                    TransferPipe tp = new TransferPipe();
12341                    try {
12342                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12343                        tp.go(fd);
12344                    } finally {
12345                        tp.kill();
12346                    }
12347                } catch (IOException e) {
12348                    pw.println("Failure while dumping the app: " + r);
12349                    pw.flush();
12350                } catch (RemoteException e) {
12351                    pw.println("Got a RemoteException while dumping the app " + r);
12352                    pw.flush();
12353                }
12354            }
12355        }
12356    }
12357
12358    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12359        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12360        if (procs == null) {
12361            pw.println("No process found for: " + args[0]);
12362            return;
12363        }
12364
12365        pw.println("Applications Database Info:");
12366
12367        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12368            ProcessRecord r = procs.get(i);
12369            if (r.thread != null) {
12370                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12371                pw.flush();
12372                try {
12373                    TransferPipe tp = new TransferPipe();
12374                    try {
12375                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12376                        tp.go(fd);
12377                    } finally {
12378                        tp.kill();
12379                    }
12380                } catch (IOException e) {
12381                    pw.println("Failure while dumping the app: " + r);
12382                    pw.flush();
12383                } catch (RemoteException e) {
12384                    pw.println("Got a RemoteException while dumping the app " + r);
12385                    pw.flush();
12386                }
12387            }
12388        }
12389    }
12390
12391    final static class MemItem {
12392        final boolean isProc;
12393        final String label;
12394        final String shortLabel;
12395        final long pss;
12396        final int id;
12397        final boolean hasActivities;
12398        ArrayList<MemItem> subitems;
12399
12400        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12401                boolean _hasActivities) {
12402            isProc = true;
12403            label = _label;
12404            shortLabel = _shortLabel;
12405            pss = _pss;
12406            id = _id;
12407            hasActivities = _hasActivities;
12408        }
12409
12410        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12411            isProc = false;
12412            label = _label;
12413            shortLabel = _shortLabel;
12414            pss = _pss;
12415            id = _id;
12416            hasActivities = false;
12417        }
12418    }
12419
12420    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12421            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12422        if (sort && !isCompact) {
12423            Collections.sort(items, new Comparator<MemItem>() {
12424                @Override
12425                public int compare(MemItem lhs, MemItem rhs) {
12426                    if (lhs.pss < rhs.pss) {
12427                        return 1;
12428                    } else if (lhs.pss > rhs.pss) {
12429                        return -1;
12430                    }
12431                    return 0;
12432                }
12433            });
12434        }
12435
12436        for (int i=0; i<items.size(); i++) {
12437            MemItem mi = items.get(i);
12438            if (!isCompact) {
12439                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12440            } else if (mi.isProc) {
12441                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12442                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12443                pw.println(mi.hasActivities ? ",a" : ",e");
12444            } else {
12445                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12446                pw.println(mi.pss);
12447            }
12448            if (mi.subitems != null) {
12449                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12450                        true, isCompact);
12451            }
12452        }
12453    }
12454
12455    // These are in KB.
12456    static final long[] DUMP_MEM_BUCKETS = new long[] {
12457        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12458        120*1024, 160*1024, 200*1024,
12459        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12460        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12461    };
12462
12463    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12464            boolean stackLike) {
12465        int start = label.lastIndexOf('.');
12466        if (start >= 0) start++;
12467        else start = 0;
12468        int end = label.length();
12469        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12470            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12471                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12472                out.append(bucket);
12473                out.append(stackLike ? "MB." : "MB ");
12474                out.append(label, start, end);
12475                return;
12476            }
12477        }
12478        out.append(memKB/1024);
12479        out.append(stackLike ? "MB." : "MB ");
12480        out.append(label, start, end);
12481    }
12482
12483    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12484            ProcessList.NATIVE_ADJ,
12485            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12486            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12487            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12488            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12489            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12490    };
12491    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12492            "Native",
12493            "System", "Persistent", "Foreground",
12494            "Visible", "Perceptible",
12495            "Heavy Weight", "Backup",
12496            "A Services", "Home",
12497            "Previous", "B Services", "Cached"
12498    };
12499    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12500            "native",
12501            "sys", "pers", "fore",
12502            "vis", "percept",
12503            "heavy", "backup",
12504            "servicea", "home",
12505            "prev", "serviceb", "cached"
12506    };
12507
12508    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12509            long realtime, boolean isCheckinRequest, boolean isCompact) {
12510        if (isCheckinRequest || isCompact) {
12511            // short checkin version
12512            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12513        } else {
12514            pw.println("Applications Memory Usage (kB):");
12515            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12516        }
12517    }
12518
12519    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12520            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12521        boolean dumpDetails = false;
12522        boolean dumpFullDetails = false;
12523        boolean dumpDalvik = false;
12524        boolean oomOnly = false;
12525        boolean isCompact = false;
12526        boolean localOnly = false;
12527
12528        int opti = 0;
12529        while (opti < args.length) {
12530            String opt = args[opti];
12531            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12532                break;
12533            }
12534            opti++;
12535            if ("-a".equals(opt)) {
12536                dumpDetails = true;
12537                dumpFullDetails = true;
12538                dumpDalvik = true;
12539            } else if ("-d".equals(opt)) {
12540                dumpDalvik = true;
12541            } else if ("-c".equals(opt)) {
12542                isCompact = true;
12543            } else if ("--oom".equals(opt)) {
12544                oomOnly = true;
12545            } else if ("--local".equals(opt)) {
12546                localOnly = true;
12547            } else if ("-h".equals(opt)) {
12548                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12549                pw.println("  -a: include all available information for each process.");
12550                pw.println("  -d: include dalvik details when dumping process details.");
12551                pw.println("  -c: dump in a compact machine-parseable representation.");
12552                pw.println("  --oom: only show processes organized by oom adj.");
12553                pw.println("  --local: only collect details locally, don't call process.");
12554                pw.println("If [process] is specified it can be the name or ");
12555                pw.println("pid of a specific process to dump.");
12556                return;
12557            } else {
12558                pw.println("Unknown argument: " + opt + "; use -h for help");
12559            }
12560        }
12561
12562        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12563        long uptime = SystemClock.uptimeMillis();
12564        long realtime = SystemClock.elapsedRealtime();
12565        final long[] tmpLong = new long[1];
12566
12567        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12568        if (procs == null) {
12569            // No Java processes.  Maybe they want to print a native process.
12570            if (args != null && args.length > opti
12571                    && args[opti].charAt(0) != '-') {
12572                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12573                        = new ArrayList<ProcessCpuTracker.Stats>();
12574                updateCpuStatsNow();
12575                int findPid = -1;
12576                try {
12577                    findPid = Integer.parseInt(args[opti]);
12578                } catch (NumberFormatException e) {
12579                }
12580                synchronized (mProcessCpuThread) {
12581                    final int N = mProcessCpuTracker.countStats();
12582                    for (int i=0; i<N; i++) {
12583                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12584                        if (st.pid == findPid || (st.baseName != null
12585                                && st.baseName.equals(args[opti]))) {
12586                            nativeProcs.add(st);
12587                        }
12588                    }
12589                }
12590                if (nativeProcs.size() > 0) {
12591                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12592                            isCompact);
12593                    Debug.MemoryInfo mi = null;
12594                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12595                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12596                        final int pid = r.pid;
12597                        if (!isCheckinRequest && dumpDetails) {
12598                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12599                        }
12600                        if (mi == null) {
12601                            mi = new Debug.MemoryInfo();
12602                        }
12603                        if (dumpDetails || (!brief && !oomOnly)) {
12604                            Debug.getMemoryInfo(pid, mi);
12605                        } else {
12606                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12607                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12608                        }
12609                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12610                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12611                        if (isCheckinRequest) {
12612                            pw.println();
12613                        }
12614                    }
12615                    return;
12616                }
12617            }
12618            pw.println("No process found for: " + args[opti]);
12619            return;
12620        }
12621
12622        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12623            dumpDetails = true;
12624        }
12625
12626        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12627
12628        String[] innerArgs = new String[args.length-opti];
12629        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12630
12631        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12632        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12633        long nativePss=0, dalvikPss=0, otherPss=0;
12634        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12635
12636        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12637        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12638                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12639
12640        long totalPss = 0;
12641        long cachedPss = 0;
12642
12643        Debug.MemoryInfo mi = null;
12644        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12645            final ProcessRecord r = procs.get(i);
12646            final IApplicationThread thread;
12647            final int pid;
12648            final int oomAdj;
12649            final boolean hasActivities;
12650            synchronized (this) {
12651                thread = r.thread;
12652                pid = r.pid;
12653                oomAdj = r.getSetAdjWithServices();
12654                hasActivities = r.activities.size() > 0;
12655            }
12656            if (thread != null) {
12657                if (!isCheckinRequest && dumpDetails) {
12658                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12659                }
12660                if (mi == null) {
12661                    mi = new Debug.MemoryInfo();
12662                }
12663                if (dumpDetails || (!brief && !oomOnly)) {
12664                    Debug.getMemoryInfo(pid, mi);
12665                } else {
12666                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12667                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12668                }
12669                if (dumpDetails) {
12670                    if (localOnly) {
12671                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12672                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12673                        if (isCheckinRequest) {
12674                            pw.println();
12675                        }
12676                    } else {
12677                        try {
12678                            pw.flush();
12679                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12680                                    dumpDalvik, innerArgs);
12681                        } catch (RemoteException e) {
12682                            if (!isCheckinRequest) {
12683                                pw.println("Got RemoteException!");
12684                                pw.flush();
12685                            }
12686                        }
12687                    }
12688                }
12689
12690                final long myTotalPss = mi.getTotalPss();
12691                final long myTotalUss = mi.getTotalUss();
12692
12693                synchronized (this) {
12694                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12695                        // Record this for posterity if the process has been stable.
12696                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12697                    }
12698                }
12699
12700                if (!isCheckinRequest && mi != null) {
12701                    totalPss += myTotalPss;
12702                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12703                            (hasActivities ? " / activities)" : ")"),
12704                            r.processName, myTotalPss, pid, hasActivities);
12705                    procMems.add(pssItem);
12706                    procMemsMap.put(pid, pssItem);
12707
12708                    nativePss += mi.nativePss;
12709                    dalvikPss += mi.dalvikPss;
12710                    otherPss += mi.otherPss;
12711                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12712                        long mem = mi.getOtherPss(j);
12713                        miscPss[j] += mem;
12714                        otherPss -= mem;
12715                    }
12716
12717                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12718                        cachedPss += myTotalPss;
12719                    }
12720
12721                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12722                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12723                                || oomIndex == (oomPss.length-1)) {
12724                            oomPss[oomIndex] += myTotalPss;
12725                            if (oomProcs[oomIndex] == null) {
12726                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12727                            }
12728                            oomProcs[oomIndex].add(pssItem);
12729                            break;
12730                        }
12731                    }
12732                }
12733            }
12734        }
12735
12736        long nativeProcTotalPss = 0;
12737
12738        if (!isCheckinRequest && procs.size() > 1) {
12739            // If we are showing aggregations, also look for native processes to
12740            // include so that our aggregations are more accurate.
12741            updateCpuStatsNow();
12742            synchronized (mProcessCpuThread) {
12743                final int N = mProcessCpuTracker.countStats();
12744                for (int i=0; i<N; i++) {
12745                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12746                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12747                        if (mi == null) {
12748                            mi = new Debug.MemoryInfo();
12749                        }
12750                        if (!brief && !oomOnly) {
12751                            Debug.getMemoryInfo(st.pid, mi);
12752                        } else {
12753                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12754                            mi.nativePrivateDirty = (int)tmpLong[0];
12755                        }
12756
12757                        final long myTotalPss = mi.getTotalPss();
12758                        totalPss += myTotalPss;
12759                        nativeProcTotalPss += myTotalPss;
12760
12761                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12762                                st.name, myTotalPss, st.pid, false);
12763                        procMems.add(pssItem);
12764
12765                        nativePss += mi.nativePss;
12766                        dalvikPss += mi.dalvikPss;
12767                        otherPss += mi.otherPss;
12768                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12769                            long mem = mi.getOtherPss(j);
12770                            miscPss[j] += mem;
12771                            otherPss -= mem;
12772                        }
12773                        oomPss[0] += myTotalPss;
12774                        if (oomProcs[0] == null) {
12775                            oomProcs[0] = new ArrayList<MemItem>();
12776                        }
12777                        oomProcs[0].add(pssItem);
12778                    }
12779                }
12780            }
12781
12782            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12783
12784            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12785            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12786            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12787            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12788                String label = Debug.MemoryInfo.getOtherLabel(j);
12789                catMems.add(new MemItem(label, label, miscPss[j], j));
12790            }
12791
12792            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12793            for (int j=0; j<oomPss.length; j++) {
12794                if (oomPss[j] != 0) {
12795                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12796                            : DUMP_MEM_OOM_LABEL[j];
12797                    MemItem item = new MemItem(label, label, oomPss[j],
12798                            DUMP_MEM_OOM_ADJ[j]);
12799                    item.subitems = oomProcs[j];
12800                    oomMems.add(item);
12801                }
12802            }
12803
12804            if (!brief && !oomOnly && !isCompact) {
12805                pw.println();
12806                pw.println("Total PSS by process:");
12807                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12808                pw.println();
12809            }
12810            if (!isCompact) {
12811                pw.println("Total PSS by OOM adjustment:");
12812            }
12813            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12814            if (!brief && !oomOnly) {
12815                PrintWriter out = categoryPw != null ? categoryPw : pw;
12816                if (!isCompact) {
12817                    out.println();
12818                    out.println("Total PSS by category:");
12819                }
12820                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12821            }
12822            if (!isCompact) {
12823                pw.println();
12824            }
12825            MemInfoReader memInfo = new MemInfoReader();
12826            memInfo.readMemInfo();
12827            if (nativeProcTotalPss > 0) {
12828                synchronized (this) {
12829                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12830                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12831                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12832                            nativeProcTotalPss);
12833                }
12834            }
12835            if (!brief) {
12836                if (!isCompact) {
12837                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12838                    pw.print(" kB (status ");
12839                    switch (mLastMemoryLevel) {
12840                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12841                            pw.println("normal)");
12842                            break;
12843                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12844                            pw.println("moderate)");
12845                            break;
12846                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12847                            pw.println("low)");
12848                            break;
12849                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12850                            pw.println("critical)");
12851                            break;
12852                        default:
12853                            pw.print(mLastMemoryLevel);
12854                            pw.println(")");
12855                            break;
12856                    }
12857                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12858                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12859                            pw.print(cachedPss); pw.print(" cached pss + ");
12860                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12861                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12862                } else {
12863                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12864                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12865                            + memInfo.getFreeSizeKb()); pw.print(",");
12866                    pw.println(totalPss - cachedPss);
12867                }
12868            }
12869            if (!isCompact) {
12870                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12871                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12872                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12873                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12874                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12875                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12876                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12877                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12878                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12879                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12880                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12881            }
12882            if (!brief) {
12883                if (memInfo.getZramTotalSizeKb() != 0) {
12884                    if (!isCompact) {
12885                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12886                                pw.print(" kB physical used for ");
12887                                pw.print(memInfo.getSwapTotalSizeKb()
12888                                        - memInfo.getSwapFreeSizeKb());
12889                                pw.print(" kB in swap (");
12890                                pw.print(memInfo.getSwapTotalSizeKb());
12891                                pw.println(" kB total swap)");
12892                    } else {
12893                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12894                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12895                                pw.println(memInfo.getSwapFreeSizeKb());
12896                    }
12897                }
12898                final int[] SINGLE_LONG_FORMAT = new int[] {
12899                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12900                };
12901                long[] longOut = new long[1];
12902                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12903                        SINGLE_LONG_FORMAT, null, longOut, null);
12904                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12905                longOut[0] = 0;
12906                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12907                        SINGLE_LONG_FORMAT, null, longOut, null);
12908                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12909                longOut[0] = 0;
12910                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12911                        SINGLE_LONG_FORMAT, null, longOut, null);
12912                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12913                longOut[0] = 0;
12914                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12915                        SINGLE_LONG_FORMAT, null, longOut, null);
12916                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12917                if (!isCompact) {
12918                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12919                        pw.print("      KSM: "); pw.print(sharing);
12920                                pw.print(" kB saved from shared ");
12921                                pw.print(shared); pw.println(" kB");
12922                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12923                                pw.print(voltile); pw.println(" kB volatile");
12924                    }
12925                    pw.print("   Tuning: ");
12926                    pw.print(ActivityManager.staticGetMemoryClass());
12927                    pw.print(" (large ");
12928                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12929                    pw.print("), oom ");
12930                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12931                    pw.print(" kB");
12932                    pw.print(", restore limit ");
12933                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12934                    pw.print(" kB");
12935                    if (ActivityManager.isLowRamDeviceStatic()) {
12936                        pw.print(" (low-ram)");
12937                    }
12938                    if (ActivityManager.isHighEndGfx()) {
12939                        pw.print(" (high-end-gfx)");
12940                    }
12941                    pw.println();
12942                } else {
12943                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12944                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12945                    pw.println(voltile);
12946                    pw.print("tuning,");
12947                    pw.print(ActivityManager.staticGetMemoryClass());
12948                    pw.print(',');
12949                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12950                    pw.print(',');
12951                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12952                    if (ActivityManager.isLowRamDeviceStatic()) {
12953                        pw.print(",low-ram");
12954                    }
12955                    if (ActivityManager.isHighEndGfx()) {
12956                        pw.print(",high-end-gfx");
12957                    }
12958                    pw.println();
12959                }
12960            }
12961        }
12962    }
12963
12964    /**
12965     * Searches array of arguments for the specified string
12966     * @param args array of argument strings
12967     * @param value value to search for
12968     * @return true if the value is contained in the array
12969     */
12970    private static boolean scanArgs(String[] args, String value) {
12971        if (args != null) {
12972            for (String arg : args) {
12973                if (value.equals(arg)) {
12974                    return true;
12975                }
12976            }
12977        }
12978        return false;
12979    }
12980
12981    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12982            ContentProviderRecord cpr, boolean always) {
12983        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12984
12985        if (!inLaunching || always) {
12986            synchronized (cpr) {
12987                cpr.launchingApp = null;
12988                cpr.notifyAll();
12989            }
12990            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12991            String names[] = cpr.info.authority.split(";");
12992            for (int j = 0; j < names.length; j++) {
12993                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12994            }
12995        }
12996
12997        for (int i=0; i<cpr.connections.size(); i++) {
12998            ContentProviderConnection conn = cpr.connections.get(i);
12999            if (conn.waiting) {
13000                // If this connection is waiting for the provider, then we don't
13001                // need to mess with its process unless we are always removing
13002                // or for some reason the provider is not currently launching.
13003                if (inLaunching && !always) {
13004                    continue;
13005                }
13006            }
13007            ProcessRecord capp = conn.client;
13008            conn.dead = true;
13009            if (conn.stableCount > 0) {
13010                if (!capp.persistent && capp.thread != null
13011                        && capp.pid != 0
13012                        && capp.pid != MY_PID) {
13013                    killUnneededProcessLocked(capp, "depends on provider "
13014                            + cpr.name.flattenToShortString()
13015                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13016                }
13017            } else if (capp.thread != null && conn.provider.provider != null) {
13018                try {
13019                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13020                } catch (RemoteException e) {
13021                }
13022                // In the protocol here, we don't expect the client to correctly
13023                // clean up this connection, we'll just remove it.
13024                cpr.connections.remove(i);
13025                conn.client.conProviders.remove(conn);
13026            }
13027        }
13028
13029        if (inLaunching && always) {
13030            mLaunchingProviders.remove(cpr);
13031        }
13032        return inLaunching;
13033    }
13034
13035    /**
13036     * Main code for cleaning up a process when it has gone away.  This is
13037     * called both as a result of the process dying, or directly when stopping
13038     * a process when running in single process mode.
13039     */
13040    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13041            boolean restarting, boolean allowRestart, int index) {
13042        if (index >= 0) {
13043            removeLruProcessLocked(app);
13044            ProcessList.remove(app.pid);
13045        }
13046
13047        mProcessesToGc.remove(app);
13048        mPendingPssProcesses.remove(app);
13049
13050        // Dismiss any open dialogs.
13051        if (app.crashDialog != null && !app.forceCrashReport) {
13052            app.crashDialog.dismiss();
13053            app.crashDialog = null;
13054        }
13055        if (app.anrDialog != null) {
13056            app.anrDialog.dismiss();
13057            app.anrDialog = null;
13058        }
13059        if (app.waitDialog != null) {
13060            app.waitDialog.dismiss();
13061            app.waitDialog = null;
13062        }
13063
13064        app.crashing = false;
13065        app.notResponding = false;
13066
13067        app.resetPackageList(mProcessStats);
13068        app.unlinkDeathRecipient();
13069        app.makeInactive(mProcessStats);
13070        app.forcingToForeground = null;
13071        updateProcessForegroundLocked(app, false, false);
13072        app.foregroundActivities = false;
13073        app.hasShownUi = false;
13074        app.treatLikeActivity = false;
13075        app.hasAboveClient = false;
13076        app.hasClientActivities = false;
13077
13078        mServices.killServicesLocked(app, allowRestart);
13079
13080        boolean restart = false;
13081
13082        // Remove published content providers.
13083        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13084            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13085            final boolean always = app.bad || !allowRestart;
13086            if (removeDyingProviderLocked(app, cpr, always) || always) {
13087                // We left the provider in the launching list, need to
13088                // restart it.
13089                restart = true;
13090            }
13091
13092            cpr.provider = null;
13093            cpr.proc = null;
13094        }
13095        app.pubProviders.clear();
13096
13097        // Take care of any launching providers waiting for this process.
13098        if (checkAppInLaunchingProvidersLocked(app, false)) {
13099            restart = true;
13100        }
13101
13102        // Unregister from connected content providers.
13103        if (!app.conProviders.isEmpty()) {
13104            for (int i=0; i<app.conProviders.size(); i++) {
13105                ContentProviderConnection conn = app.conProviders.get(i);
13106                conn.provider.connections.remove(conn);
13107            }
13108            app.conProviders.clear();
13109        }
13110
13111        // At this point there may be remaining entries in mLaunchingProviders
13112        // where we were the only one waiting, so they are no longer of use.
13113        // Look for these and clean up if found.
13114        // XXX Commented out for now.  Trying to figure out a way to reproduce
13115        // the actual situation to identify what is actually going on.
13116        if (false) {
13117            for (int i=0; i<mLaunchingProviders.size(); i++) {
13118                ContentProviderRecord cpr = (ContentProviderRecord)
13119                        mLaunchingProviders.get(i);
13120                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13121                    synchronized (cpr) {
13122                        cpr.launchingApp = null;
13123                        cpr.notifyAll();
13124                    }
13125                }
13126            }
13127        }
13128
13129        skipCurrentReceiverLocked(app);
13130
13131        // Unregister any receivers.
13132        for (int i=app.receivers.size()-1; i>=0; i--) {
13133            removeReceiverLocked(app.receivers.valueAt(i));
13134        }
13135        app.receivers.clear();
13136
13137        // If the app is undergoing backup, tell the backup manager about it
13138        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13139            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13140                    + mBackupTarget.appInfo + " died during backup");
13141            try {
13142                IBackupManager bm = IBackupManager.Stub.asInterface(
13143                        ServiceManager.getService(Context.BACKUP_SERVICE));
13144                bm.agentDisconnected(app.info.packageName);
13145            } catch (RemoteException e) {
13146                // can't happen; backup manager is local
13147            }
13148        }
13149
13150        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13151            ProcessChangeItem item = mPendingProcessChanges.get(i);
13152            if (item.pid == app.pid) {
13153                mPendingProcessChanges.remove(i);
13154                mAvailProcessChanges.add(item);
13155            }
13156        }
13157        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13158
13159        // If the caller is restarting this app, then leave it in its
13160        // current lists and let the caller take care of it.
13161        if (restarting) {
13162            return;
13163        }
13164
13165        if (!app.persistent || app.isolated) {
13166            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13167                    "Removing non-persistent process during cleanup: " + app);
13168            mProcessNames.remove(app.processName, app.uid);
13169            mIsolatedProcesses.remove(app.uid);
13170            if (mHeavyWeightProcess == app) {
13171                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13172                        mHeavyWeightProcess.userId, 0));
13173                mHeavyWeightProcess = null;
13174            }
13175        } else if (!app.removed) {
13176            // This app is persistent, so we need to keep its record around.
13177            // If it is not already on the pending app list, add it there
13178            // and start a new process for it.
13179            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13180                mPersistentStartingProcesses.add(app);
13181                restart = true;
13182            }
13183        }
13184        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13185                "Clean-up removing on hold: " + app);
13186        mProcessesOnHold.remove(app);
13187
13188        if (app == mHomeProcess) {
13189            mHomeProcess = null;
13190        }
13191        if (app == mPreviousProcess) {
13192            mPreviousProcess = null;
13193        }
13194
13195        if (restart && !app.isolated) {
13196            // We have components that still need to be running in the
13197            // process, so re-launch it.
13198            mProcessNames.put(app.processName, app.uid, app);
13199            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13200        } else if (app.pid > 0 && app.pid != MY_PID) {
13201            // Goodbye!
13202            boolean removed;
13203            synchronized (mPidsSelfLocked) {
13204                mPidsSelfLocked.remove(app.pid);
13205                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13206            }
13207            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13208                    app.processName, app.info.uid);
13209            if (app.isolated) {
13210                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13211            }
13212            app.setPid(0);
13213        }
13214    }
13215
13216    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13217        // Look through the content providers we are waiting to have launched,
13218        // and if any run in this process then either schedule a restart of
13219        // the process or kill the client waiting for it if this process has
13220        // gone bad.
13221        int NL = mLaunchingProviders.size();
13222        boolean restart = false;
13223        for (int i=0; i<NL; i++) {
13224            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13225            if (cpr.launchingApp == app) {
13226                if (!alwaysBad && !app.bad) {
13227                    restart = true;
13228                } else {
13229                    removeDyingProviderLocked(app, cpr, true);
13230                    // cpr should have been removed from mLaunchingProviders
13231                    NL = mLaunchingProviders.size();
13232                    i--;
13233                }
13234            }
13235        }
13236        return restart;
13237    }
13238
13239    // =========================================================
13240    // SERVICES
13241    // =========================================================
13242
13243    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13244            int flags) {
13245        enforceNotIsolatedCaller("getServices");
13246        synchronized (this) {
13247            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13248        }
13249    }
13250
13251    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13252        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13253        synchronized (this) {
13254            return mServices.getRunningServiceControlPanelLocked(name);
13255        }
13256    }
13257
13258    public ComponentName startService(IApplicationThread caller, Intent service,
13259            String resolvedType, int userId) {
13260        enforceNotIsolatedCaller("startService");
13261        // Refuse possible leaked file descriptors
13262        if (service != null && service.hasFileDescriptors() == true) {
13263            throw new IllegalArgumentException("File descriptors passed in Intent");
13264        }
13265
13266        if (DEBUG_SERVICE)
13267            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13268        synchronized(this) {
13269            final int callingPid = Binder.getCallingPid();
13270            final int callingUid = Binder.getCallingUid();
13271            final long origId = Binder.clearCallingIdentity();
13272            ComponentName res = mServices.startServiceLocked(caller, service,
13273                    resolvedType, callingPid, callingUid, userId);
13274            Binder.restoreCallingIdentity(origId);
13275            return res;
13276        }
13277    }
13278
13279    ComponentName startServiceInPackage(int uid,
13280            Intent service, String resolvedType, int userId) {
13281        synchronized(this) {
13282            if (DEBUG_SERVICE)
13283                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13284            final long origId = Binder.clearCallingIdentity();
13285            ComponentName res = mServices.startServiceLocked(null, service,
13286                    resolvedType, -1, uid, userId);
13287            Binder.restoreCallingIdentity(origId);
13288            return res;
13289        }
13290    }
13291
13292    public int stopService(IApplicationThread caller, Intent service,
13293            String resolvedType, int userId) {
13294        enforceNotIsolatedCaller("stopService");
13295        // Refuse possible leaked file descriptors
13296        if (service != null && service.hasFileDescriptors() == true) {
13297            throw new IllegalArgumentException("File descriptors passed in Intent");
13298        }
13299
13300        synchronized(this) {
13301            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13302        }
13303    }
13304
13305    public IBinder peekService(Intent service, String resolvedType) {
13306        enforceNotIsolatedCaller("peekService");
13307        // Refuse possible leaked file descriptors
13308        if (service != null && service.hasFileDescriptors() == true) {
13309            throw new IllegalArgumentException("File descriptors passed in Intent");
13310        }
13311        synchronized(this) {
13312            return mServices.peekServiceLocked(service, resolvedType);
13313        }
13314    }
13315
13316    public boolean stopServiceToken(ComponentName className, IBinder token,
13317            int startId) {
13318        synchronized(this) {
13319            return mServices.stopServiceTokenLocked(className, token, startId);
13320        }
13321    }
13322
13323    public void setServiceForeground(ComponentName className, IBinder token,
13324            int id, Notification notification, boolean removeNotification) {
13325        synchronized(this) {
13326            mServices.setServiceForegroundLocked(className, token, id, notification,
13327                    removeNotification);
13328        }
13329    }
13330
13331    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13332            boolean requireFull, String name, String callerPackage) {
13333        final int callingUserId = UserHandle.getUserId(callingUid);
13334        if (callingUserId != userId) {
13335            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13336                if ((requireFull || checkComponentPermission(
13337                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13338                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13339                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13340                                callingPid, callingUid, -1, true)
13341                                != PackageManager.PERMISSION_GRANTED) {
13342                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13343                        // In this case, they would like to just execute as their
13344                        // owner user instead of failing.
13345                        userId = callingUserId;
13346                    } else {
13347                        StringBuilder builder = new StringBuilder(128);
13348                        builder.append("Permission Denial: ");
13349                        builder.append(name);
13350                        if (callerPackage != null) {
13351                            builder.append(" from ");
13352                            builder.append(callerPackage);
13353                        }
13354                        builder.append(" asks to run as user ");
13355                        builder.append(userId);
13356                        builder.append(" but is calling from user ");
13357                        builder.append(UserHandle.getUserId(callingUid));
13358                        builder.append("; this requires ");
13359                        builder.append(INTERACT_ACROSS_USERS_FULL);
13360                        if (!requireFull) {
13361                            builder.append(" or ");
13362                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13363                        }
13364                        String msg = builder.toString();
13365                        Slog.w(TAG, msg);
13366                        throw new SecurityException(msg);
13367                    }
13368                }
13369            }
13370            if (userId == UserHandle.USER_CURRENT
13371                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13372                // Note that we may be accessing this outside of a lock...
13373                // shouldn't be a big deal, if this is being called outside
13374                // of a locked context there is intrinsically a race with
13375                // the value the caller will receive and someone else changing it.
13376                userId = mCurrentUserId;
13377            }
13378            if (!allowAll && userId < 0) {
13379                throw new IllegalArgumentException(
13380                        "Call does not support special user #" + userId);
13381            }
13382        }
13383        return userId;
13384    }
13385
13386    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13387            String className, int flags) {
13388        boolean result = false;
13389        // For apps that don't have pre-defined UIDs, check for permission
13390        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13391            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13392                if (ActivityManager.checkUidPermission(
13393                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13394                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13395                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13396                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13397                            + " requests FLAG_SINGLE_USER, but app does not hold "
13398                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13399                    Slog.w(TAG, msg);
13400                    throw new SecurityException(msg);
13401                }
13402                // Permission passed
13403                result = true;
13404            }
13405        } else if ("system".equals(componentProcessName)) {
13406            result = true;
13407        } else {
13408            // App with pre-defined UID, check if it's a persistent app
13409            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13410        }
13411        if (DEBUG_MU) {
13412            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13413                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13414        }
13415        return result;
13416    }
13417
13418    /**
13419     * Checks to see if the caller is in the same app as the singleton
13420     * component, or the component is in a special app. It allows special apps
13421     * to export singleton components but prevents exporting singleton
13422     * components for regular apps.
13423     */
13424    boolean isValidSingletonCall(int callingUid, int componentUid) {
13425        int componentAppId = UserHandle.getAppId(componentUid);
13426        return UserHandle.isSameApp(callingUid, componentUid)
13427                || componentAppId == Process.SYSTEM_UID
13428                || componentAppId == Process.PHONE_UID
13429                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13430                        == PackageManager.PERMISSION_GRANTED;
13431    }
13432
13433    public int bindService(IApplicationThread caller, IBinder token,
13434            Intent service, String resolvedType,
13435            IServiceConnection connection, int flags, int userId) {
13436        enforceNotIsolatedCaller("bindService");
13437        // Refuse possible leaked file descriptors
13438        if (service != null && service.hasFileDescriptors() == true) {
13439            throw new IllegalArgumentException("File descriptors passed in Intent");
13440        }
13441
13442        synchronized(this) {
13443            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13444                    connection, flags, userId);
13445        }
13446    }
13447
13448    public boolean unbindService(IServiceConnection connection) {
13449        synchronized (this) {
13450            return mServices.unbindServiceLocked(connection);
13451        }
13452    }
13453
13454    public void publishService(IBinder token, Intent intent, IBinder service) {
13455        // Refuse possible leaked file descriptors
13456        if (intent != null && intent.hasFileDescriptors() == true) {
13457            throw new IllegalArgumentException("File descriptors passed in Intent");
13458        }
13459
13460        synchronized(this) {
13461            if (!(token instanceof ServiceRecord)) {
13462                throw new IllegalArgumentException("Invalid service token");
13463            }
13464            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13465        }
13466    }
13467
13468    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13469        // Refuse possible leaked file descriptors
13470        if (intent != null && intent.hasFileDescriptors() == true) {
13471            throw new IllegalArgumentException("File descriptors passed in Intent");
13472        }
13473
13474        synchronized(this) {
13475            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13476        }
13477    }
13478
13479    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13480        synchronized(this) {
13481            if (!(token instanceof ServiceRecord)) {
13482                throw new IllegalArgumentException("Invalid service token");
13483            }
13484            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13485        }
13486    }
13487
13488    // =========================================================
13489    // BACKUP AND RESTORE
13490    // =========================================================
13491
13492    // Cause the target app to be launched if necessary and its backup agent
13493    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13494    // activity manager to announce its creation.
13495    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13496        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13497        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13498
13499        synchronized(this) {
13500            // !!! TODO: currently no check here that we're already bound
13501            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13502            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13503            synchronized (stats) {
13504                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13505            }
13506
13507            // Backup agent is now in use, its package can't be stopped.
13508            try {
13509                AppGlobals.getPackageManager().setPackageStoppedState(
13510                        app.packageName, false, UserHandle.getUserId(app.uid));
13511            } catch (RemoteException e) {
13512            } catch (IllegalArgumentException e) {
13513                Slog.w(TAG, "Failed trying to unstop package "
13514                        + app.packageName + ": " + e);
13515            }
13516
13517            BackupRecord r = new BackupRecord(ss, app, backupMode);
13518            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13519                    ? new ComponentName(app.packageName, app.backupAgentName)
13520                    : new ComponentName("android", "FullBackupAgent");
13521            // startProcessLocked() returns existing proc's record if it's already running
13522            ProcessRecord proc = startProcessLocked(app.processName, app,
13523                    false, 0, "backup", hostingName, false, false, false);
13524            if (proc == null) {
13525                Slog.e(TAG, "Unable to start backup agent process " + r);
13526                return false;
13527            }
13528
13529            r.app = proc;
13530            mBackupTarget = r;
13531            mBackupAppName = app.packageName;
13532
13533            // Try not to kill the process during backup
13534            updateOomAdjLocked(proc);
13535
13536            // If the process is already attached, schedule the creation of the backup agent now.
13537            // If it is not yet live, this will be done when it attaches to the framework.
13538            if (proc.thread != null) {
13539                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13540                try {
13541                    proc.thread.scheduleCreateBackupAgent(app,
13542                            compatibilityInfoForPackageLocked(app), backupMode);
13543                } catch (RemoteException e) {
13544                    // Will time out on the backup manager side
13545                }
13546            } else {
13547                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13548            }
13549            // Invariants: at this point, the target app process exists and the application
13550            // is either already running or in the process of coming up.  mBackupTarget and
13551            // mBackupAppName describe the app, so that when it binds back to the AM we
13552            // know that it's scheduled for a backup-agent operation.
13553        }
13554
13555        return true;
13556    }
13557
13558    @Override
13559    public void clearPendingBackup() {
13560        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13561        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13562
13563        synchronized (this) {
13564            mBackupTarget = null;
13565            mBackupAppName = null;
13566        }
13567    }
13568
13569    // A backup agent has just come up
13570    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13571        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13572                + " = " + agent);
13573
13574        synchronized(this) {
13575            if (!agentPackageName.equals(mBackupAppName)) {
13576                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13577                return;
13578            }
13579        }
13580
13581        long oldIdent = Binder.clearCallingIdentity();
13582        try {
13583            IBackupManager bm = IBackupManager.Stub.asInterface(
13584                    ServiceManager.getService(Context.BACKUP_SERVICE));
13585            bm.agentConnected(agentPackageName, agent);
13586        } catch (RemoteException e) {
13587            // can't happen; the backup manager service is local
13588        } catch (Exception e) {
13589            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13590            e.printStackTrace();
13591        } finally {
13592            Binder.restoreCallingIdentity(oldIdent);
13593        }
13594    }
13595
13596    // done with this agent
13597    public void unbindBackupAgent(ApplicationInfo appInfo) {
13598        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13599        if (appInfo == null) {
13600            Slog.w(TAG, "unbind backup agent for null app");
13601            return;
13602        }
13603
13604        synchronized(this) {
13605            try {
13606                if (mBackupAppName == null) {
13607                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13608                    return;
13609                }
13610
13611                if (!mBackupAppName.equals(appInfo.packageName)) {
13612                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13613                    return;
13614                }
13615
13616                // Not backing this app up any more; reset its OOM adjustment
13617                final ProcessRecord proc = mBackupTarget.app;
13618                updateOomAdjLocked(proc);
13619
13620                // If the app crashed during backup, 'thread' will be null here
13621                if (proc.thread != null) {
13622                    try {
13623                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13624                                compatibilityInfoForPackageLocked(appInfo));
13625                    } catch (Exception e) {
13626                        Slog.e(TAG, "Exception when unbinding backup agent:");
13627                        e.printStackTrace();
13628                    }
13629                }
13630            } finally {
13631                mBackupTarget = null;
13632                mBackupAppName = null;
13633            }
13634        }
13635    }
13636    // =========================================================
13637    // BROADCASTS
13638    // =========================================================
13639
13640    private final List getStickiesLocked(String action, IntentFilter filter,
13641            List cur, int userId) {
13642        final ContentResolver resolver = mContext.getContentResolver();
13643        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13644        if (stickies == null) {
13645            return cur;
13646        }
13647        final ArrayList<Intent> list = stickies.get(action);
13648        if (list == null) {
13649            return cur;
13650        }
13651        int N = list.size();
13652        for (int i=0; i<N; i++) {
13653            Intent intent = list.get(i);
13654            if (filter.match(resolver, intent, true, TAG) >= 0) {
13655                if (cur == null) {
13656                    cur = new ArrayList<Intent>();
13657                }
13658                cur.add(intent);
13659            }
13660        }
13661        return cur;
13662    }
13663
13664    boolean isPendingBroadcastProcessLocked(int pid) {
13665        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13666                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13667    }
13668
13669    void skipPendingBroadcastLocked(int pid) {
13670            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13671            for (BroadcastQueue queue : mBroadcastQueues) {
13672                queue.skipPendingBroadcastLocked(pid);
13673            }
13674    }
13675
13676    // The app just attached; send any pending broadcasts that it should receive
13677    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13678        boolean didSomething = false;
13679        for (BroadcastQueue queue : mBroadcastQueues) {
13680            didSomething |= queue.sendPendingBroadcastsLocked(app);
13681        }
13682        return didSomething;
13683    }
13684
13685    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13686            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13687        enforceNotIsolatedCaller("registerReceiver");
13688        int callingUid;
13689        int callingPid;
13690        synchronized(this) {
13691            ProcessRecord callerApp = null;
13692            if (caller != null) {
13693                callerApp = getRecordForAppLocked(caller);
13694                if (callerApp == null) {
13695                    throw new SecurityException(
13696                            "Unable to find app for caller " + caller
13697                            + " (pid=" + Binder.getCallingPid()
13698                            + ") when registering receiver " + receiver);
13699                }
13700                if (callerApp.info.uid != Process.SYSTEM_UID &&
13701                        !callerApp.pkgList.containsKey(callerPackage) &&
13702                        !"android".equals(callerPackage)) {
13703                    throw new SecurityException("Given caller package " + callerPackage
13704                            + " is not running in process " + callerApp);
13705                }
13706                callingUid = callerApp.info.uid;
13707                callingPid = callerApp.pid;
13708            } else {
13709                callerPackage = null;
13710                callingUid = Binder.getCallingUid();
13711                callingPid = Binder.getCallingPid();
13712            }
13713
13714            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13715                    true, true, "registerReceiver", callerPackage);
13716
13717            List allSticky = null;
13718
13719            // Look for any matching sticky broadcasts...
13720            Iterator actions = filter.actionsIterator();
13721            if (actions != null) {
13722                while (actions.hasNext()) {
13723                    String action = (String)actions.next();
13724                    allSticky = getStickiesLocked(action, filter, allSticky,
13725                            UserHandle.USER_ALL);
13726                    allSticky = getStickiesLocked(action, filter, allSticky,
13727                            UserHandle.getUserId(callingUid));
13728                }
13729            } else {
13730                allSticky = getStickiesLocked(null, filter, allSticky,
13731                        UserHandle.USER_ALL);
13732                allSticky = getStickiesLocked(null, filter, allSticky,
13733                        UserHandle.getUserId(callingUid));
13734            }
13735
13736            // The first sticky in the list is returned directly back to
13737            // the client.
13738            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13739
13740            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13741                    + ": " + sticky);
13742
13743            if (receiver == null) {
13744                return sticky;
13745            }
13746
13747            ReceiverList rl
13748                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13749            if (rl == null) {
13750                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13751                        userId, receiver);
13752                if (rl.app != null) {
13753                    rl.app.receivers.add(rl);
13754                } else {
13755                    try {
13756                        receiver.asBinder().linkToDeath(rl, 0);
13757                    } catch (RemoteException e) {
13758                        return sticky;
13759                    }
13760                    rl.linkedToDeath = true;
13761                }
13762                mRegisteredReceivers.put(receiver.asBinder(), rl);
13763            } else if (rl.uid != callingUid) {
13764                throw new IllegalArgumentException(
13765                        "Receiver requested to register for uid " + callingUid
13766                        + " was previously registered for uid " + rl.uid);
13767            } else if (rl.pid != callingPid) {
13768                throw new IllegalArgumentException(
13769                        "Receiver requested to register for pid " + callingPid
13770                        + " was previously registered for pid " + rl.pid);
13771            } else if (rl.userId != userId) {
13772                throw new IllegalArgumentException(
13773                        "Receiver requested to register for user " + userId
13774                        + " was previously registered for user " + rl.userId);
13775            }
13776            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13777                    permission, callingUid, userId);
13778            rl.add(bf);
13779            if (!bf.debugCheck()) {
13780                Slog.w(TAG, "==> For Dynamic broadast");
13781            }
13782            mReceiverResolver.addFilter(bf);
13783
13784            // Enqueue broadcasts for all existing stickies that match
13785            // this filter.
13786            if (allSticky != null) {
13787                ArrayList receivers = new ArrayList();
13788                receivers.add(bf);
13789
13790                int N = allSticky.size();
13791                for (int i=0; i<N; i++) {
13792                    Intent intent = (Intent)allSticky.get(i);
13793                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13794                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13795                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13796                            null, null, false, true, true, -1);
13797                    queue.enqueueParallelBroadcastLocked(r);
13798                    queue.scheduleBroadcastsLocked();
13799                }
13800            }
13801
13802            return sticky;
13803        }
13804    }
13805
13806    public void unregisterReceiver(IIntentReceiver receiver) {
13807        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13808
13809        final long origId = Binder.clearCallingIdentity();
13810        try {
13811            boolean doTrim = false;
13812
13813            synchronized(this) {
13814                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13815                if (rl != null) {
13816                    if (rl.curBroadcast != null) {
13817                        BroadcastRecord r = rl.curBroadcast;
13818                        final boolean doNext = finishReceiverLocked(
13819                                receiver.asBinder(), r.resultCode, r.resultData,
13820                                r.resultExtras, r.resultAbort);
13821                        if (doNext) {
13822                            doTrim = true;
13823                            r.queue.processNextBroadcast(false);
13824                        }
13825                    }
13826
13827                    if (rl.app != null) {
13828                        rl.app.receivers.remove(rl);
13829                    }
13830                    removeReceiverLocked(rl);
13831                    if (rl.linkedToDeath) {
13832                        rl.linkedToDeath = false;
13833                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13834                    }
13835                }
13836            }
13837
13838            // If we actually concluded any broadcasts, we might now be able
13839            // to trim the recipients' apps from our working set
13840            if (doTrim) {
13841                trimApplications();
13842                return;
13843            }
13844
13845        } finally {
13846            Binder.restoreCallingIdentity(origId);
13847        }
13848    }
13849
13850    void removeReceiverLocked(ReceiverList rl) {
13851        mRegisteredReceivers.remove(rl.receiver.asBinder());
13852        int N = rl.size();
13853        for (int i=0; i<N; i++) {
13854            mReceiverResolver.removeFilter(rl.get(i));
13855        }
13856    }
13857
13858    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13859        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13860            ProcessRecord r = mLruProcesses.get(i);
13861            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13862                try {
13863                    r.thread.dispatchPackageBroadcast(cmd, packages);
13864                } catch (RemoteException ex) {
13865                }
13866            }
13867        }
13868    }
13869
13870    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13871            int[] users) {
13872        List<ResolveInfo> receivers = null;
13873        try {
13874            HashSet<ComponentName> singleUserReceivers = null;
13875            boolean scannedFirstReceivers = false;
13876            for (int user : users) {
13877                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13878                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13879                if (user != 0 && newReceivers != null) {
13880                    // If this is not the primary user, we need to check for
13881                    // any receivers that should be filtered out.
13882                    for (int i=0; i<newReceivers.size(); i++) {
13883                        ResolveInfo ri = newReceivers.get(i);
13884                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13885                            newReceivers.remove(i);
13886                            i--;
13887                        }
13888                    }
13889                }
13890                if (newReceivers != null && newReceivers.size() == 0) {
13891                    newReceivers = null;
13892                }
13893                if (receivers == null) {
13894                    receivers = newReceivers;
13895                } else if (newReceivers != null) {
13896                    // We need to concatenate the additional receivers
13897                    // found with what we have do far.  This would be easy,
13898                    // but we also need to de-dup any receivers that are
13899                    // singleUser.
13900                    if (!scannedFirstReceivers) {
13901                        // Collect any single user receivers we had already retrieved.
13902                        scannedFirstReceivers = true;
13903                        for (int i=0; i<receivers.size(); i++) {
13904                            ResolveInfo ri = receivers.get(i);
13905                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13906                                ComponentName cn = new ComponentName(
13907                                        ri.activityInfo.packageName, ri.activityInfo.name);
13908                                if (singleUserReceivers == null) {
13909                                    singleUserReceivers = new HashSet<ComponentName>();
13910                                }
13911                                singleUserReceivers.add(cn);
13912                            }
13913                        }
13914                    }
13915                    // Add the new results to the existing results, tracking
13916                    // and de-dupping single user receivers.
13917                    for (int i=0; i<newReceivers.size(); i++) {
13918                        ResolveInfo ri = newReceivers.get(i);
13919                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13920                            ComponentName cn = new ComponentName(
13921                                    ri.activityInfo.packageName, ri.activityInfo.name);
13922                            if (singleUserReceivers == null) {
13923                                singleUserReceivers = new HashSet<ComponentName>();
13924                            }
13925                            if (!singleUserReceivers.contains(cn)) {
13926                                singleUserReceivers.add(cn);
13927                                receivers.add(ri);
13928                            }
13929                        } else {
13930                            receivers.add(ri);
13931                        }
13932                    }
13933                }
13934            }
13935        } catch (RemoteException ex) {
13936            // pm is in same process, this will never happen.
13937        }
13938        return receivers;
13939    }
13940
13941    private final int broadcastIntentLocked(ProcessRecord callerApp,
13942            String callerPackage, Intent intent, String resolvedType,
13943            IIntentReceiver resultTo, int resultCode, String resultData,
13944            Bundle map, String requiredPermission, int appOp,
13945            boolean ordered, boolean sticky, int callingPid, int callingUid,
13946            int userId) {
13947        intent = new Intent(intent);
13948
13949        // By default broadcasts do not go to stopped apps.
13950        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13951
13952        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13953            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13954            + " ordered=" + ordered + " userid=" + userId);
13955        if ((resultTo != null) && !ordered) {
13956            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13957        }
13958
13959        userId = handleIncomingUser(callingPid, callingUid, userId,
13960                true, false, "broadcast", callerPackage);
13961
13962        // Make sure that the user who is receiving this broadcast is started.
13963        // If not, we will just skip it.
13964
13965
13966        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13967            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13968                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13969                Slog.w(TAG, "Skipping broadcast of " + intent
13970                        + ": user " + userId + " is stopped");
13971                return ActivityManager.BROADCAST_SUCCESS;
13972            }
13973        }
13974
13975        /*
13976         * Prevent non-system code (defined here to be non-persistent
13977         * processes) from sending protected broadcasts.
13978         */
13979        int callingAppId = UserHandle.getAppId(callingUid);
13980        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13981            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13982            || callingAppId == Process.NFC_UID || callingUid == 0) {
13983            // Always okay.
13984        } else if (callerApp == null || !callerApp.persistent) {
13985            try {
13986                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13987                        intent.getAction())) {
13988                    String msg = "Permission Denial: not allowed to send broadcast "
13989                            + intent.getAction() + " from pid="
13990                            + callingPid + ", uid=" + callingUid;
13991                    Slog.w(TAG, msg);
13992                    throw new SecurityException(msg);
13993                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13994                    // Special case for compatibility: we don't want apps to send this,
13995                    // but historically it has not been protected and apps may be using it
13996                    // to poke their own app widget.  So, instead of making it protected,
13997                    // just limit it to the caller.
13998                    if (callerApp == null) {
13999                        String msg = "Permission Denial: not allowed to send broadcast "
14000                                + intent.getAction() + " from unknown caller.";
14001                        Slog.w(TAG, msg);
14002                        throw new SecurityException(msg);
14003                    } else if (intent.getComponent() != null) {
14004                        // They are good enough to send to an explicit component...  verify
14005                        // it is being sent to the calling app.
14006                        if (!intent.getComponent().getPackageName().equals(
14007                                callerApp.info.packageName)) {
14008                            String msg = "Permission Denial: not allowed to send broadcast "
14009                                    + intent.getAction() + " to "
14010                                    + intent.getComponent().getPackageName() + " from "
14011                                    + callerApp.info.packageName;
14012                            Slog.w(TAG, msg);
14013                            throw new SecurityException(msg);
14014                        }
14015                    } else {
14016                        // Limit broadcast to their own package.
14017                        intent.setPackage(callerApp.info.packageName);
14018                    }
14019                }
14020            } catch (RemoteException e) {
14021                Slog.w(TAG, "Remote exception", e);
14022                return ActivityManager.BROADCAST_SUCCESS;
14023            }
14024        }
14025
14026        // Handle special intents: if this broadcast is from the package
14027        // manager about a package being removed, we need to remove all of
14028        // its activities from the history stack.
14029        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14030                intent.getAction());
14031        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14032                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14033                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14034                || uidRemoved) {
14035            if (checkComponentPermission(
14036                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14037                    callingPid, callingUid, -1, true)
14038                    == PackageManager.PERMISSION_GRANTED) {
14039                if (uidRemoved) {
14040                    final Bundle intentExtras = intent.getExtras();
14041                    final int uid = intentExtras != null
14042                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14043                    if (uid >= 0) {
14044                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14045                        synchronized (bs) {
14046                            bs.removeUidStatsLocked(uid);
14047                        }
14048                        mAppOpsService.uidRemoved(uid);
14049                    }
14050                } else {
14051                    // If resources are unavailable just force stop all
14052                    // those packages and flush the attribute cache as well.
14053                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14054                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14055                        if (list != null && (list.length > 0)) {
14056                            for (String pkg : list) {
14057                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14058                                        "storage unmount");
14059                            }
14060                            sendPackageBroadcastLocked(
14061                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14062                        }
14063                    } else {
14064                        Uri data = intent.getData();
14065                        String ssp;
14066                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14067                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14068                                    intent.getAction());
14069                            boolean fullUninstall = removed &&
14070                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14071                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14072                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14073                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14074                                        false, fullUninstall, userId,
14075                                        removed ? "pkg removed" : "pkg changed");
14076                            }
14077                            if (removed) {
14078                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14079                                        new String[] {ssp}, userId);
14080                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14081                                    mAppOpsService.packageRemoved(
14082                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14083
14084                                    // Remove all permissions granted from/to this package
14085                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14086                                }
14087                            }
14088                        }
14089                    }
14090                }
14091            } else {
14092                String msg = "Permission Denial: " + intent.getAction()
14093                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14094                        + ", uid=" + callingUid + ")"
14095                        + " requires "
14096                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14097                Slog.w(TAG, msg);
14098                throw new SecurityException(msg);
14099            }
14100
14101        // Special case for adding a package: by default turn on compatibility
14102        // mode.
14103        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14104            Uri data = intent.getData();
14105            String ssp;
14106            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14107                mCompatModePackages.handlePackageAddedLocked(ssp,
14108                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14109            }
14110        }
14111
14112        /*
14113         * If this is the time zone changed action, queue up a message that will reset the timezone
14114         * of all currently running processes. This message will get queued up before the broadcast
14115         * happens.
14116         */
14117        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14118            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14119        }
14120
14121        /*
14122         * If the user set the time, let all running processes know.
14123         */
14124        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14125            final int is24Hour = intent.getBooleanExtra(
14126                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14127            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14128        }
14129
14130        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14131            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14132        }
14133
14134        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14135            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14136            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14137        }
14138
14139        // Add to the sticky list if requested.
14140        if (sticky) {
14141            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14142                    callingPid, callingUid)
14143                    != PackageManager.PERMISSION_GRANTED) {
14144                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14145                        + callingPid + ", uid=" + callingUid
14146                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14147                Slog.w(TAG, msg);
14148                throw new SecurityException(msg);
14149            }
14150            if (requiredPermission != null) {
14151                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14152                        + " and enforce permission " + requiredPermission);
14153                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14154            }
14155            if (intent.getComponent() != null) {
14156                throw new SecurityException(
14157                        "Sticky broadcasts can't target a specific component");
14158            }
14159            // We use userId directly here, since the "all" target is maintained
14160            // as a separate set of sticky broadcasts.
14161            if (userId != UserHandle.USER_ALL) {
14162                // But first, if this is not a broadcast to all users, then
14163                // make sure it doesn't conflict with an existing broadcast to
14164                // all users.
14165                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14166                        UserHandle.USER_ALL);
14167                if (stickies != null) {
14168                    ArrayList<Intent> list = stickies.get(intent.getAction());
14169                    if (list != null) {
14170                        int N = list.size();
14171                        int i;
14172                        for (i=0; i<N; i++) {
14173                            if (intent.filterEquals(list.get(i))) {
14174                                throw new IllegalArgumentException(
14175                                        "Sticky broadcast " + intent + " for user "
14176                                        + userId + " conflicts with existing global broadcast");
14177                            }
14178                        }
14179                    }
14180                }
14181            }
14182            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14183            if (stickies == null) {
14184                stickies = new ArrayMap<String, ArrayList<Intent>>();
14185                mStickyBroadcasts.put(userId, stickies);
14186            }
14187            ArrayList<Intent> list = stickies.get(intent.getAction());
14188            if (list == null) {
14189                list = new ArrayList<Intent>();
14190                stickies.put(intent.getAction(), list);
14191            }
14192            int N = list.size();
14193            int i;
14194            for (i=0; i<N; i++) {
14195                if (intent.filterEquals(list.get(i))) {
14196                    // This sticky already exists, replace it.
14197                    list.set(i, new Intent(intent));
14198                    break;
14199                }
14200            }
14201            if (i >= N) {
14202                list.add(new Intent(intent));
14203            }
14204        }
14205
14206        int[] users;
14207        if (userId == UserHandle.USER_ALL) {
14208            // Caller wants broadcast to go to all started users.
14209            users = mStartedUserArray;
14210        } else {
14211            // Caller wants broadcast to go to one specific user.
14212            users = new int[] {userId};
14213        }
14214
14215        // Figure out who all will receive this broadcast.
14216        List receivers = null;
14217        List<BroadcastFilter> registeredReceivers = null;
14218        // Need to resolve the intent to interested receivers...
14219        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14220                 == 0) {
14221            receivers = collectReceiverComponents(intent, resolvedType, users);
14222        }
14223        if (intent.getComponent() == null) {
14224            registeredReceivers = mReceiverResolver.queryIntent(intent,
14225                    resolvedType, false, userId);
14226        }
14227
14228        final boolean replacePending =
14229                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14230
14231        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14232                + " replacePending=" + replacePending);
14233
14234        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14235        if (!ordered && NR > 0) {
14236            // If we are not serializing this broadcast, then send the
14237            // registered receivers separately so they don't wait for the
14238            // components to be launched.
14239            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14240            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14241                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14242                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14243                    ordered, sticky, false, userId);
14244            if (DEBUG_BROADCAST) Slog.v(
14245                    TAG, "Enqueueing parallel broadcast " + r);
14246            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14247            if (!replaced) {
14248                queue.enqueueParallelBroadcastLocked(r);
14249                queue.scheduleBroadcastsLocked();
14250            }
14251            registeredReceivers = null;
14252            NR = 0;
14253        }
14254
14255        // Merge into one list.
14256        int ir = 0;
14257        if (receivers != null) {
14258            // A special case for PACKAGE_ADDED: do not allow the package
14259            // being added to see this broadcast.  This prevents them from
14260            // using this as a back door to get run as soon as they are
14261            // installed.  Maybe in the future we want to have a special install
14262            // broadcast or such for apps, but we'd like to deliberately make
14263            // this decision.
14264            String skipPackages[] = null;
14265            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14266                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14267                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14268                Uri data = intent.getData();
14269                if (data != null) {
14270                    String pkgName = data.getSchemeSpecificPart();
14271                    if (pkgName != null) {
14272                        skipPackages = new String[] { pkgName };
14273                    }
14274                }
14275            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14276                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14277            }
14278            if (skipPackages != null && (skipPackages.length > 0)) {
14279                for (String skipPackage : skipPackages) {
14280                    if (skipPackage != null) {
14281                        int NT = receivers.size();
14282                        for (int it=0; it<NT; it++) {
14283                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14284                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14285                                receivers.remove(it);
14286                                it--;
14287                                NT--;
14288                            }
14289                        }
14290                    }
14291                }
14292            }
14293
14294            int NT = receivers != null ? receivers.size() : 0;
14295            int it = 0;
14296            ResolveInfo curt = null;
14297            BroadcastFilter curr = null;
14298            while (it < NT && ir < NR) {
14299                if (curt == null) {
14300                    curt = (ResolveInfo)receivers.get(it);
14301                }
14302                if (curr == null) {
14303                    curr = registeredReceivers.get(ir);
14304                }
14305                if (curr.getPriority() >= curt.priority) {
14306                    // Insert this broadcast record into the final list.
14307                    receivers.add(it, curr);
14308                    ir++;
14309                    curr = null;
14310                    it++;
14311                    NT++;
14312                } else {
14313                    // Skip to the next ResolveInfo in the final list.
14314                    it++;
14315                    curt = null;
14316                }
14317            }
14318        }
14319        while (ir < NR) {
14320            if (receivers == null) {
14321                receivers = new ArrayList();
14322            }
14323            receivers.add(registeredReceivers.get(ir));
14324            ir++;
14325        }
14326
14327        if ((receivers != null && receivers.size() > 0)
14328                || resultTo != null) {
14329            BroadcastQueue queue = broadcastQueueForIntent(intent);
14330            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14331                    callerPackage, callingPid, callingUid, resolvedType,
14332                    requiredPermission, appOp, receivers, resultTo, resultCode,
14333                    resultData, map, ordered, sticky, false, userId);
14334            if (DEBUG_BROADCAST) Slog.v(
14335                    TAG, "Enqueueing ordered broadcast " + r
14336                    + ": prev had " + queue.mOrderedBroadcasts.size());
14337            if (DEBUG_BROADCAST) {
14338                int seq = r.intent.getIntExtra("seq", -1);
14339                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14340            }
14341            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14342            if (!replaced) {
14343                queue.enqueueOrderedBroadcastLocked(r);
14344                queue.scheduleBroadcastsLocked();
14345            }
14346        }
14347
14348        return ActivityManager.BROADCAST_SUCCESS;
14349    }
14350
14351    final Intent verifyBroadcastLocked(Intent intent) {
14352        // Refuse possible leaked file descriptors
14353        if (intent != null && intent.hasFileDescriptors() == true) {
14354            throw new IllegalArgumentException("File descriptors passed in Intent");
14355        }
14356
14357        int flags = intent.getFlags();
14358
14359        if (!mProcessesReady) {
14360            // if the caller really truly claims to know what they're doing, go
14361            // ahead and allow the broadcast without launching any receivers
14362            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14363                intent = new Intent(intent);
14364                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14365            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14366                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14367                        + " before boot completion");
14368                throw new IllegalStateException("Cannot broadcast before boot completed");
14369            }
14370        }
14371
14372        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14373            throw new IllegalArgumentException(
14374                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14375        }
14376
14377        return intent;
14378    }
14379
14380    public final int broadcastIntent(IApplicationThread caller,
14381            Intent intent, String resolvedType, IIntentReceiver resultTo,
14382            int resultCode, String resultData, Bundle map,
14383            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14384        enforceNotIsolatedCaller("broadcastIntent");
14385        synchronized(this) {
14386            intent = verifyBroadcastLocked(intent);
14387
14388            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14389            final int callingPid = Binder.getCallingPid();
14390            final int callingUid = Binder.getCallingUid();
14391            final long origId = Binder.clearCallingIdentity();
14392            int res = broadcastIntentLocked(callerApp,
14393                    callerApp != null ? callerApp.info.packageName : null,
14394                    intent, resolvedType, resultTo,
14395                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14396                    callingPid, callingUid, userId);
14397            Binder.restoreCallingIdentity(origId);
14398            return res;
14399        }
14400    }
14401
14402    int broadcastIntentInPackage(String packageName, int uid,
14403            Intent intent, String resolvedType, IIntentReceiver resultTo,
14404            int resultCode, String resultData, Bundle map,
14405            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14406        synchronized(this) {
14407            intent = verifyBroadcastLocked(intent);
14408
14409            final long origId = Binder.clearCallingIdentity();
14410            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14411                    resultTo, resultCode, resultData, map, requiredPermission,
14412                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14413            Binder.restoreCallingIdentity(origId);
14414            return res;
14415        }
14416    }
14417
14418    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14419        // Refuse possible leaked file descriptors
14420        if (intent != null && intent.hasFileDescriptors() == true) {
14421            throw new IllegalArgumentException("File descriptors passed in Intent");
14422        }
14423
14424        userId = handleIncomingUser(Binder.getCallingPid(),
14425                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14426
14427        synchronized(this) {
14428            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14429                    != PackageManager.PERMISSION_GRANTED) {
14430                String msg = "Permission Denial: unbroadcastIntent() from pid="
14431                        + Binder.getCallingPid()
14432                        + ", uid=" + Binder.getCallingUid()
14433                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14434                Slog.w(TAG, msg);
14435                throw new SecurityException(msg);
14436            }
14437            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14438            if (stickies != null) {
14439                ArrayList<Intent> list = stickies.get(intent.getAction());
14440                if (list != null) {
14441                    int N = list.size();
14442                    int i;
14443                    for (i=0; i<N; i++) {
14444                        if (intent.filterEquals(list.get(i))) {
14445                            list.remove(i);
14446                            break;
14447                        }
14448                    }
14449                    if (list.size() <= 0) {
14450                        stickies.remove(intent.getAction());
14451                    }
14452                }
14453                if (stickies.size() <= 0) {
14454                    mStickyBroadcasts.remove(userId);
14455                }
14456            }
14457        }
14458    }
14459
14460    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14461            String resultData, Bundle resultExtras, boolean resultAbort) {
14462        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14463        if (r == null) {
14464            Slog.w(TAG, "finishReceiver called but not found on queue");
14465            return false;
14466        }
14467
14468        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14469    }
14470
14471    void backgroundServicesFinishedLocked(int userId) {
14472        for (BroadcastQueue queue : mBroadcastQueues) {
14473            queue.backgroundServicesFinishedLocked(userId);
14474        }
14475    }
14476
14477    public void finishReceiver(IBinder who, int resultCode, String resultData,
14478            Bundle resultExtras, boolean resultAbort) {
14479        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14480
14481        // Refuse possible leaked file descriptors
14482        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14483            throw new IllegalArgumentException("File descriptors passed in Bundle");
14484        }
14485
14486        final long origId = Binder.clearCallingIdentity();
14487        try {
14488            boolean doNext = false;
14489            BroadcastRecord r;
14490
14491            synchronized(this) {
14492                r = broadcastRecordForReceiverLocked(who);
14493                if (r != null) {
14494                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14495                        resultData, resultExtras, resultAbort, true);
14496                }
14497            }
14498
14499            if (doNext) {
14500                r.queue.processNextBroadcast(false);
14501            }
14502            trimApplications();
14503        } finally {
14504            Binder.restoreCallingIdentity(origId);
14505        }
14506    }
14507
14508    // =========================================================
14509    // INSTRUMENTATION
14510    // =========================================================
14511
14512    public boolean startInstrumentation(ComponentName className,
14513            String profileFile, int flags, Bundle arguments,
14514            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14515            int userId, String abiOverride) {
14516        enforceNotIsolatedCaller("startInstrumentation");
14517        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14518                userId, false, true, "startInstrumentation", null);
14519        // Refuse possible leaked file descriptors
14520        if (arguments != null && arguments.hasFileDescriptors()) {
14521            throw new IllegalArgumentException("File descriptors passed in Bundle");
14522        }
14523
14524        synchronized(this) {
14525            InstrumentationInfo ii = null;
14526            ApplicationInfo ai = null;
14527            try {
14528                ii = mContext.getPackageManager().getInstrumentationInfo(
14529                    className, STOCK_PM_FLAGS);
14530                ai = AppGlobals.getPackageManager().getApplicationInfo(
14531                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14532            } catch (PackageManager.NameNotFoundException e) {
14533            } catch (RemoteException e) {
14534            }
14535            if (ii == null) {
14536                reportStartInstrumentationFailure(watcher, className,
14537                        "Unable to find instrumentation info for: " + className);
14538                return false;
14539            }
14540            if (ai == null) {
14541                reportStartInstrumentationFailure(watcher, className,
14542                        "Unable to find instrumentation target package: " + ii.targetPackage);
14543                return false;
14544            }
14545
14546            int match = mContext.getPackageManager().checkSignatures(
14547                    ii.targetPackage, ii.packageName);
14548            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14549                String msg = "Permission Denial: starting instrumentation "
14550                        + className + " from pid="
14551                        + Binder.getCallingPid()
14552                        + ", uid=" + Binder.getCallingPid()
14553                        + " not allowed because package " + ii.packageName
14554                        + " does not have a signature matching the target "
14555                        + ii.targetPackage;
14556                reportStartInstrumentationFailure(watcher, className, msg);
14557                throw new SecurityException(msg);
14558            }
14559
14560            final long origId = Binder.clearCallingIdentity();
14561            // Instrumentation can kill and relaunch even persistent processes
14562            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14563                    "start instr");
14564            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14565            app.instrumentationClass = className;
14566            app.instrumentationInfo = ai;
14567            app.instrumentationProfileFile = profileFile;
14568            app.instrumentationArguments = arguments;
14569            app.instrumentationWatcher = watcher;
14570            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14571            app.instrumentationResultClass = className;
14572            Binder.restoreCallingIdentity(origId);
14573        }
14574
14575        return true;
14576    }
14577
14578    /**
14579     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14580     * error to the logs, but if somebody is watching, send the report there too.  This enables
14581     * the "am" command to report errors with more information.
14582     *
14583     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14584     * @param cn The component name of the instrumentation.
14585     * @param report The error report.
14586     */
14587    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14588            ComponentName cn, String report) {
14589        Slog.w(TAG, report);
14590        try {
14591            if (watcher != null) {
14592                Bundle results = new Bundle();
14593                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14594                results.putString("Error", report);
14595                watcher.instrumentationStatus(cn, -1, results);
14596            }
14597        } catch (RemoteException e) {
14598            Slog.w(TAG, e);
14599        }
14600    }
14601
14602    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14603        if (app.instrumentationWatcher != null) {
14604            try {
14605                // NOTE:  IInstrumentationWatcher *must* be oneway here
14606                app.instrumentationWatcher.instrumentationFinished(
14607                    app.instrumentationClass,
14608                    resultCode,
14609                    results);
14610            } catch (RemoteException e) {
14611            }
14612        }
14613        if (app.instrumentationUiAutomationConnection != null) {
14614            try {
14615                app.instrumentationUiAutomationConnection.shutdown();
14616            } catch (RemoteException re) {
14617                /* ignore */
14618            }
14619            // Only a UiAutomation can set this flag and now that
14620            // it is finished we make sure it is reset to its default.
14621            mUserIsMonkey = false;
14622        }
14623        app.instrumentationWatcher = null;
14624        app.instrumentationUiAutomationConnection = null;
14625        app.instrumentationClass = null;
14626        app.instrumentationInfo = null;
14627        app.instrumentationProfileFile = null;
14628        app.instrumentationArguments = null;
14629
14630        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14631                "finished inst");
14632    }
14633
14634    public void finishInstrumentation(IApplicationThread target,
14635            int resultCode, Bundle results) {
14636        int userId = UserHandle.getCallingUserId();
14637        // Refuse possible leaked file descriptors
14638        if (results != null && results.hasFileDescriptors()) {
14639            throw new IllegalArgumentException("File descriptors passed in Intent");
14640        }
14641
14642        synchronized(this) {
14643            ProcessRecord app = getRecordForAppLocked(target);
14644            if (app == null) {
14645                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14646                return;
14647            }
14648            final long origId = Binder.clearCallingIdentity();
14649            finishInstrumentationLocked(app, resultCode, results);
14650            Binder.restoreCallingIdentity(origId);
14651        }
14652    }
14653
14654    // =========================================================
14655    // CONFIGURATION
14656    // =========================================================
14657
14658    public ConfigurationInfo getDeviceConfigurationInfo() {
14659        ConfigurationInfo config = new ConfigurationInfo();
14660        synchronized (this) {
14661            config.reqTouchScreen = mConfiguration.touchscreen;
14662            config.reqKeyboardType = mConfiguration.keyboard;
14663            config.reqNavigation = mConfiguration.navigation;
14664            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14665                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14666                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14667            }
14668            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14669                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14670                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14671            }
14672            config.reqGlEsVersion = GL_ES_VERSION;
14673        }
14674        return config;
14675    }
14676
14677    ActivityStack getFocusedStack() {
14678        return mStackSupervisor.getFocusedStack();
14679    }
14680
14681    public Configuration getConfiguration() {
14682        Configuration ci;
14683        synchronized(this) {
14684            ci = new Configuration(mConfiguration);
14685        }
14686        return ci;
14687    }
14688
14689    public void updatePersistentConfiguration(Configuration values) {
14690        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14691                "updateConfiguration()");
14692        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14693                "updateConfiguration()");
14694        if (values == null) {
14695            throw new NullPointerException("Configuration must not be null");
14696        }
14697
14698        synchronized(this) {
14699            final long origId = Binder.clearCallingIdentity();
14700            updateConfigurationLocked(values, null, true, false);
14701            Binder.restoreCallingIdentity(origId);
14702        }
14703    }
14704
14705    public void updateConfiguration(Configuration values) {
14706        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14707                "updateConfiguration()");
14708
14709        synchronized(this) {
14710            if (values == null && mWindowManager != null) {
14711                // sentinel: fetch the current configuration from the window manager
14712                values = mWindowManager.computeNewConfiguration();
14713            }
14714
14715            if (mWindowManager != null) {
14716                mProcessList.applyDisplaySize(mWindowManager);
14717            }
14718
14719            final long origId = Binder.clearCallingIdentity();
14720            if (values != null) {
14721                Settings.System.clearConfiguration(values);
14722            }
14723            updateConfigurationLocked(values, null, false, false);
14724            Binder.restoreCallingIdentity(origId);
14725        }
14726    }
14727
14728    /**
14729     * Do either or both things: (1) change the current configuration, and (2)
14730     * make sure the given activity is running with the (now) current
14731     * configuration.  Returns true if the activity has been left running, or
14732     * false if <var>starting</var> is being destroyed to match the new
14733     * configuration.
14734     * @param persistent TODO
14735     */
14736    boolean updateConfigurationLocked(Configuration values,
14737            ActivityRecord starting, boolean persistent, boolean initLocale) {
14738        int changes = 0;
14739
14740        if (values != null) {
14741            Configuration newConfig = new Configuration(mConfiguration);
14742            changes = newConfig.updateFrom(values);
14743            if (changes != 0) {
14744                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14745                    Slog.i(TAG, "Updating configuration to: " + values);
14746                }
14747
14748                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14749
14750                if (values.locale != null && !initLocale) {
14751                    saveLocaleLocked(values.locale,
14752                                     !values.locale.equals(mConfiguration.locale),
14753                                     values.userSetLocale);
14754                }
14755
14756                mConfigurationSeq++;
14757                if (mConfigurationSeq <= 0) {
14758                    mConfigurationSeq = 1;
14759                }
14760                newConfig.seq = mConfigurationSeq;
14761                mConfiguration = newConfig;
14762                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14763                mUsageStatsService.noteStartConfig(newConfig);
14764
14765                final Configuration configCopy = new Configuration(mConfiguration);
14766
14767                // TODO: If our config changes, should we auto dismiss any currently
14768                // showing dialogs?
14769                mShowDialogs = shouldShowDialogs(newConfig);
14770
14771                AttributeCache ac = AttributeCache.instance();
14772                if (ac != null) {
14773                    ac.updateConfiguration(configCopy);
14774                }
14775
14776                // Make sure all resources in our process are updated
14777                // right now, so that anyone who is going to retrieve
14778                // resource values after we return will be sure to get
14779                // the new ones.  This is especially important during
14780                // boot, where the first config change needs to guarantee
14781                // all resources have that config before following boot
14782                // code is executed.
14783                mSystemThread.applyConfigurationToResources(configCopy);
14784
14785                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14786                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14787                    msg.obj = new Configuration(configCopy);
14788                    mHandler.sendMessage(msg);
14789                }
14790
14791                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14792                    ProcessRecord app = mLruProcesses.get(i);
14793                    try {
14794                        if (app.thread != null) {
14795                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14796                                    + app.processName + " new config " + mConfiguration);
14797                            app.thread.scheduleConfigurationChanged(configCopy);
14798                        }
14799                    } catch (Exception e) {
14800                    }
14801                }
14802                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14803                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14804                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14805                        | Intent.FLAG_RECEIVER_FOREGROUND);
14806                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14807                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14808                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14809                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14810                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14811                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14812                    broadcastIntentLocked(null, null, intent,
14813                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14814                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14815                }
14816            }
14817        }
14818
14819        boolean kept = true;
14820        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14821        // mainStack is null during startup.
14822        if (mainStack != null) {
14823            if (changes != 0 && starting == null) {
14824                // If the configuration changed, and the caller is not already
14825                // in the process of starting an activity, then find the top
14826                // activity to check if its configuration needs to change.
14827                starting = mainStack.topRunningActivityLocked(null);
14828            }
14829
14830            if (starting != null) {
14831                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14832                // And we need to make sure at this point that all other activities
14833                // are made visible with the correct configuration.
14834                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14835            }
14836        }
14837
14838        if (values != null && mWindowManager != null) {
14839            mWindowManager.setNewConfiguration(mConfiguration);
14840        }
14841
14842        return kept;
14843    }
14844
14845    /**
14846     * Decide based on the configuration whether we should shouw the ANR,
14847     * crash, etc dialogs.  The idea is that if there is no affordnace to
14848     * press the on-screen buttons, we shouldn't show the dialog.
14849     *
14850     * A thought: SystemUI might also want to get told about this, the Power
14851     * dialog / global actions also might want different behaviors.
14852     */
14853    private static final boolean shouldShowDialogs(Configuration config) {
14854        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14855                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14856    }
14857
14858    /**
14859     * Save the locale.  You must be inside a synchronized (this) block.
14860     */
14861    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14862        if(isDiff) {
14863            SystemProperties.set("user.language", l.getLanguage());
14864            SystemProperties.set("user.region", l.getCountry());
14865        }
14866
14867        if(isPersist) {
14868            SystemProperties.set("persist.sys.language", l.getLanguage());
14869            SystemProperties.set("persist.sys.country", l.getCountry());
14870            SystemProperties.set("persist.sys.localevar", l.getVariant());
14871        }
14872    }
14873
14874    @Override
14875    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14876        ActivityRecord srec = ActivityRecord.forToken(token);
14877        return srec != null && srec.task.affinity != null &&
14878                srec.task.affinity.equals(destAffinity);
14879    }
14880
14881    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14882            Intent resultData) {
14883
14884        synchronized (this) {
14885            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14886            if (stack != null) {
14887                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14888            }
14889            return false;
14890        }
14891    }
14892
14893    public int getLaunchedFromUid(IBinder activityToken) {
14894        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14895        if (srec == null) {
14896            return -1;
14897        }
14898        return srec.launchedFromUid;
14899    }
14900
14901    public String getLaunchedFromPackage(IBinder activityToken) {
14902        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14903        if (srec == null) {
14904            return null;
14905        }
14906        return srec.launchedFromPackage;
14907    }
14908
14909    // =========================================================
14910    // LIFETIME MANAGEMENT
14911    // =========================================================
14912
14913    // Returns which broadcast queue the app is the current [or imminent] receiver
14914    // on, or 'null' if the app is not an active broadcast recipient.
14915    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14916        BroadcastRecord r = app.curReceiver;
14917        if (r != null) {
14918            return r.queue;
14919        }
14920
14921        // It's not the current receiver, but it might be starting up to become one
14922        synchronized (this) {
14923            for (BroadcastQueue queue : mBroadcastQueues) {
14924                r = queue.mPendingBroadcast;
14925                if (r != null && r.curApp == app) {
14926                    // found it; report which queue it's in
14927                    return queue;
14928                }
14929            }
14930        }
14931
14932        return null;
14933    }
14934
14935    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14936            boolean doingAll, long now) {
14937        if (mAdjSeq == app.adjSeq) {
14938            // This adjustment has already been computed.
14939            return app.curRawAdj;
14940        }
14941
14942        if (app.thread == null) {
14943            app.adjSeq = mAdjSeq;
14944            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14945            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14946            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14947        }
14948
14949        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14950        app.adjSource = null;
14951        app.adjTarget = null;
14952        app.empty = false;
14953        app.cached = false;
14954
14955        final int activitiesSize = app.activities.size();
14956
14957        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14958            // The max adjustment doesn't allow this app to be anything
14959            // below foreground, so it is not worth doing work for it.
14960            app.adjType = "fixed";
14961            app.adjSeq = mAdjSeq;
14962            app.curRawAdj = app.maxAdj;
14963            app.foregroundActivities = false;
14964            app.keeping = true;
14965            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14966            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14967            // System processes can do UI, and when they do we want to have
14968            // them trim their memory after the user leaves the UI.  To
14969            // facilitate this, here we need to determine whether or not it
14970            // is currently showing UI.
14971            app.systemNoUi = true;
14972            if (app == TOP_APP) {
14973                app.systemNoUi = false;
14974            } else if (activitiesSize > 0) {
14975                for (int j = 0; j < activitiesSize; j++) {
14976                    final ActivityRecord r = app.activities.get(j);
14977                    if (r.visible) {
14978                        app.systemNoUi = false;
14979                    }
14980                }
14981            }
14982            if (!app.systemNoUi) {
14983                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14984            }
14985            return (app.curAdj=app.maxAdj);
14986        }
14987
14988        app.keeping = false;
14989        app.systemNoUi = false;
14990
14991        // Determine the importance of the process, starting with most
14992        // important to least, and assign an appropriate OOM adjustment.
14993        int adj;
14994        int schedGroup;
14995        int procState;
14996        boolean foregroundActivities = false;
14997        boolean interesting = false;
14998        BroadcastQueue queue;
14999        if (app == TOP_APP) {
15000            // The last app on the list is the foreground app.
15001            adj = ProcessList.FOREGROUND_APP_ADJ;
15002            schedGroup = Process.THREAD_GROUP_DEFAULT;
15003            app.adjType = "top-activity";
15004            foregroundActivities = true;
15005            interesting = true;
15006            procState = ActivityManager.PROCESS_STATE_TOP;
15007        } else if (app.instrumentationClass != null) {
15008            // Don't want to kill running instrumentation.
15009            adj = ProcessList.FOREGROUND_APP_ADJ;
15010            schedGroup = Process.THREAD_GROUP_DEFAULT;
15011            app.adjType = "instrumentation";
15012            interesting = true;
15013            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15014        } else if ((queue = isReceivingBroadcast(app)) != null) {
15015            // An app that is currently receiving a broadcast also
15016            // counts as being in the foreground for OOM killer purposes.
15017            // It's placed in a sched group based on the nature of the
15018            // broadcast as reflected by which queue it's active in.
15019            adj = ProcessList.FOREGROUND_APP_ADJ;
15020            schedGroup = (queue == mFgBroadcastQueue)
15021                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15022            app.adjType = "broadcast";
15023            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15024        } else if (app.executingServices.size() > 0) {
15025            // An app that is currently executing a service callback also
15026            // counts as being in the foreground.
15027            adj = ProcessList.FOREGROUND_APP_ADJ;
15028            schedGroup = app.execServicesFg ?
15029                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15030            app.adjType = "exec-service";
15031            procState = ActivityManager.PROCESS_STATE_SERVICE;
15032            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15033        } else {
15034            // As far as we know the process is empty.  We may change our mind later.
15035            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15036            // At this point we don't actually know the adjustment.  Use the cached adj
15037            // value that the caller wants us to.
15038            adj = cachedAdj;
15039            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15040            app.cached = true;
15041            app.empty = true;
15042            app.adjType = "cch-empty";
15043        }
15044
15045        // Examine all activities if not already foreground.
15046        if (!foregroundActivities && activitiesSize > 0) {
15047            for (int j = 0; j < activitiesSize; j++) {
15048                final ActivityRecord r = app.activities.get(j);
15049                if (r.app != app) {
15050                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15051                            + app + "?!?");
15052                    continue;
15053                }
15054                if (r.visible) {
15055                    // App has a visible activity; only upgrade adjustment.
15056                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15057                        adj = ProcessList.VISIBLE_APP_ADJ;
15058                        app.adjType = "visible";
15059                    }
15060                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15061                        procState = ActivityManager.PROCESS_STATE_TOP;
15062                    }
15063                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15064                    app.cached = false;
15065                    app.empty = false;
15066                    foregroundActivities = true;
15067                    break;
15068                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15069                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15070                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15071                        app.adjType = "pausing";
15072                    }
15073                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15074                        procState = ActivityManager.PROCESS_STATE_TOP;
15075                    }
15076                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15077                    app.cached = false;
15078                    app.empty = false;
15079                    foregroundActivities = true;
15080                } else if (r.state == ActivityState.STOPPING) {
15081                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15082                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15083                        app.adjType = "stopping";
15084                    }
15085                    // For the process state, we will at this point consider the
15086                    // process to be cached.  It will be cached either as an activity
15087                    // or empty depending on whether the activity is finishing.  We do
15088                    // this so that we can treat the process as cached for purposes of
15089                    // memory trimming (determing current memory level, trim command to
15090                    // send to process) since there can be an arbitrary number of stopping
15091                    // processes and they should soon all go into the cached state.
15092                    if (!r.finishing) {
15093                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15094                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15095                        }
15096                    }
15097                    app.cached = false;
15098                    app.empty = false;
15099                    foregroundActivities = true;
15100                } else {
15101                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15102                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15103                        app.adjType = "cch-act";
15104                    }
15105                }
15106            }
15107        }
15108
15109        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15110            if (app.foregroundServices) {
15111                // The user is aware of this app, so make it visible.
15112                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15113                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15114                app.cached = false;
15115                app.adjType = "fg-service";
15116                schedGroup = Process.THREAD_GROUP_DEFAULT;
15117            } else if (app.forcingToForeground != null) {
15118                // The user is aware of this app, so make it visible.
15119                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15120                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15121                app.cached = false;
15122                app.adjType = "force-fg";
15123                app.adjSource = app.forcingToForeground;
15124                schedGroup = Process.THREAD_GROUP_DEFAULT;
15125            }
15126        }
15127
15128        if (app.foregroundServices) {
15129            interesting = true;
15130        }
15131
15132        if (app == mHeavyWeightProcess) {
15133            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15134                // We don't want to kill the current heavy-weight process.
15135                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15136                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15137                app.cached = false;
15138                app.adjType = "heavy";
15139            }
15140            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15141                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15142            }
15143        }
15144
15145        if (app == mHomeProcess) {
15146            if (adj > ProcessList.HOME_APP_ADJ) {
15147                // This process is hosting what we currently consider to be the
15148                // home app, so we don't want to let it go into the background.
15149                adj = ProcessList.HOME_APP_ADJ;
15150                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15151                app.cached = false;
15152                app.adjType = "home";
15153            }
15154            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15155                procState = ActivityManager.PROCESS_STATE_HOME;
15156            }
15157        }
15158
15159        if (app == mPreviousProcess && app.activities.size() > 0) {
15160            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15161                // This was the previous process that showed UI to the user.
15162                // We want to try to keep it around more aggressively, to give
15163                // a good experience around switching between two apps.
15164                adj = ProcessList.PREVIOUS_APP_ADJ;
15165                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15166                app.cached = false;
15167                app.adjType = "previous";
15168            }
15169            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15170                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15171            }
15172        }
15173
15174        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15175                + " reason=" + app.adjType);
15176
15177        // By default, we use the computed adjustment.  It may be changed if
15178        // there are applications dependent on our services or providers, but
15179        // this gives us a baseline and makes sure we don't get into an
15180        // infinite recursion.
15181        app.adjSeq = mAdjSeq;
15182        app.curRawAdj = adj;
15183        app.hasStartedServices = false;
15184
15185        if (mBackupTarget != null && app == mBackupTarget.app) {
15186            // If possible we want to avoid killing apps while they're being backed up
15187            if (adj > ProcessList.BACKUP_APP_ADJ) {
15188                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15189                adj = ProcessList.BACKUP_APP_ADJ;
15190                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15191                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15192                }
15193                app.adjType = "backup";
15194                app.cached = false;
15195            }
15196            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15197                procState = ActivityManager.PROCESS_STATE_BACKUP;
15198            }
15199        }
15200
15201        boolean mayBeTop = false;
15202
15203        for (int is = app.services.size()-1;
15204                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15205                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15206                        || procState > ActivityManager.PROCESS_STATE_TOP);
15207                is--) {
15208            ServiceRecord s = app.services.valueAt(is);
15209            if (s.startRequested) {
15210                app.hasStartedServices = true;
15211                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15212                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15213                }
15214                if (app.hasShownUi && app != mHomeProcess) {
15215                    // If this process has shown some UI, let it immediately
15216                    // go to the LRU list because it may be pretty heavy with
15217                    // UI stuff.  We'll tag it with a label just to help
15218                    // debug and understand what is going on.
15219                    if (adj > ProcessList.SERVICE_ADJ) {
15220                        app.adjType = "cch-started-ui-services";
15221                    }
15222                } else {
15223                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15224                        // This service has seen some activity within
15225                        // recent memory, so we will keep its process ahead
15226                        // of the background processes.
15227                        if (adj > ProcessList.SERVICE_ADJ) {
15228                            adj = ProcessList.SERVICE_ADJ;
15229                            app.adjType = "started-services";
15230                            app.cached = false;
15231                        }
15232                    }
15233                    // If we have let the service slide into the background
15234                    // state, still have some text describing what it is doing
15235                    // even though the service no longer has an impact.
15236                    if (adj > ProcessList.SERVICE_ADJ) {
15237                        app.adjType = "cch-started-services";
15238                    }
15239                }
15240                // Don't kill this process because it is doing work; it
15241                // has said it is doing work.
15242                app.keeping = true;
15243            }
15244            for (int conni = s.connections.size()-1;
15245                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15246                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15247                            || procState > ActivityManager.PROCESS_STATE_TOP);
15248                    conni--) {
15249                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15250                for (int i = 0;
15251                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15252                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15253                                || procState > ActivityManager.PROCESS_STATE_TOP);
15254                        i++) {
15255                    // XXX should compute this based on the max of
15256                    // all connected clients.
15257                    ConnectionRecord cr = clist.get(i);
15258                    if (cr.binding.client == app) {
15259                        // Binding to ourself is not interesting.
15260                        continue;
15261                    }
15262                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15263                        ProcessRecord client = cr.binding.client;
15264                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15265                                TOP_APP, doingAll, now);
15266                        int clientProcState = client.curProcState;
15267                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15268                            // If the other app is cached for any reason, for purposes here
15269                            // we are going to consider it empty.  The specific cached state
15270                            // doesn't propagate except under certain conditions.
15271                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15272                        }
15273                        String adjType = null;
15274                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15275                            // Not doing bind OOM management, so treat
15276                            // this guy more like a started service.
15277                            if (app.hasShownUi && app != mHomeProcess) {
15278                                // If this process has shown some UI, let it immediately
15279                                // go to the LRU list because it may be pretty heavy with
15280                                // UI stuff.  We'll tag it with a label just to help
15281                                // debug and understand what is going on.
15282                                if (adj > clientAdj) {
15283                                    adjType = "cch-bound-ui-services";
15284                                }
15285                                app.cached = false;
15286                                clientAdj = adj;
15287                                clientProcState = procState;
15288                            } else {
15289                                if (now >= (s.lastActivity
15290                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15291                                    // This service has not seen activity within
15292                                    // recent memory, so allow it to drop to the
15293                                    // LRU list if there is no other reason to keep
15294                                    // it around.  We'll also tag it with a label just
15295                                    // to help debug and undertand what is going on.
15296                                    if (adj > clientAdj) {
15297                                        adjType = "cch-bound-services";
15298                                    }
15299                                    clientAdj = adj;
15300                                }
15301                            }
15302                        }
15303                        if (adj > clientAdj) {
15304                            // If this process has recently shown UI, and
15305                            // the process that is binding to it is less
15306                            // important than being visible, then we don't
15307                            // care about the binding as much as we care
15308                            // about letting this process get into the LRU
15309                            // list to be killed and restarted if needed for
15310                            // memory.
15311                            if (app.hasShownUi && app != mHomeProcess
15312                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15313                                adjType = "cch-bound-ui-services";
15314                            } else {
15315                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15316                                        |Context.BIND_IMPORTANT)) != 0) {
15317                                    adj = clientAdj;
15318                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15319                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15320                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15321                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15322                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15323                                    adj = clientAdj;
15324                                } else {
15325                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15326                                        adj = ProcessList.VISIBLE_APP_ADJ;
15327                                    }
15328                                }
15329                                if (!client.cached) {
15330                                    app.cached = false;
15331                                }
15332                                if (client.keeping) {
15333                                    app.keeping = true;
15334                                }
15335                                adjType = "service";
15336                            }
15337                        }
15338                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15339                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15340                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15341                            }
15342                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15343                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15344                                    // Special handling of clients who are in the top state.
15345                                    // We *may* want to consider this process to be in the
15346                                    // top state as well, but only if there is not another
15347                                    // reason for it to be running.  Being on the top is a
15348                                    // special state, meaning you are specifically running
15349                                    // for the current top app.  If the process is already
15350                                    // running in the background for some other reason, it
15351                                    // is more important to continue considering it to be
15352                                    // in the background state.
15353                                    mayBeTop = true;
15354                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15355                                } else {
15356                                    // Special handling for above-top states (persistent
15357                                    // processes).  These should not bring the current process
15358                                    // into the top state, since they are not on top.  Instead
15359                                    // give them the best state after that.
15360                                    clientProcState =
15361                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15362                                }
15363                            }
15364                        } else {
15365                            if (clientProcState <
15366                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15367                                clientProcState =
15368                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15369                            }
15370                        }
15371                        if (procState > clientProcState) {
15372                            procState = clientProcState;
15373                        }
15374                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15375                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15376                            app.pendingUiClean = true;
15377                        }
15378                        if (adjType != null) {
15379                            app.adjType = adjType;
15380                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15381                                    .REASON_SERVICE_IN_USE;
15382                            app.adjSource = cr.binding.client;
15383                            app.adjSourceOom = clientAdj;
15384                            app.adjTarget = s.name;
15385                        }
15386                    }
15387                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15388                        app.treatLikeActivity = true;
15389                    }
15390                    final ActivityRecord a = cr.activity;
15391                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15392                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15393                                (a.visible || a.state == ActivityState.RESUMED
15394                                 || a.state == ActivityState.PAUSING)) {
15395                            adj = ProcessList.FOREGROUND_APP_ADJ;
15396                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15397                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15398                            }
15399                            app.cached = false;
15400                            app.adjType = "service";
15401                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15402                                    .REASON_SERVICE_IN_USE;
15403                            app.adjSource = a;
15404                            app.adjSourceOom = adj;
15405                            app.adjTarget = s.name;
15406                        }
15407                    }
15408                }
15409            }
15410        }
15411
15412        for (int provi = app.pubProviders.size()-1;
15413                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15414                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15415                        || procState > ActivityManager.PROCESS_STATE_TOP);
15416                provi--) {
15417            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15418            for (int i = cpr.connections.size()-1;
15419                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15420                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15421                            || procState > ActivityManager.PROCESS_STATE_TOP);
15422                    i--) {
15423                ContentProviderConnection conn = cpr.connections.get(i);
15424                ProcessRecord client = conn.client;
15425                if (client == app) {
15426                    // Being our own client is not interesting.
15427                    continue;
15428                }
15429                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15430                int clientProcState = client.curProcState;
15431                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15432                    // If the other app is cached for any reason, for purposes here
15433                    // we are going to consider it empty.
15434                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15435                }
15436                if (adj > clientAdj) {
15437                    if (app.hasShownUi && app != mHomeProcess
15438                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15439                        app.adjType = "cch-ui-provider";
15440                    } else {
15441                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15442                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15443                        app.adjType = "provider";
15444                    }
15445                    app.cached &= client.cached;
15446                    app.keeping |= client.keeping;
15447                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15448                            .REASON_PROVIDER_IN_USE;
15449                    app.adjSource = client;
15450                    app.adjSourceOom = clientAdj;
15451                    app.adjTarget = cpr.name;
15452                }
15453                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15454                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15455                        // Special handling of clients who are in the top state.
15456                        // We *may* want to consider this process to be in the
15457                        // top state as well, but only if there is not another
15458                        // reason for it to be running.  Being on the top is a
15459                        // special state, meaning you are specifically running
15460                        // for the current top app.  If the process is already
15461                        // running in the background for some other reason, it
15462                        // is more important to continue considering it to be
15463                        // in the background state.
15464                        mayBeTop = true;
15465                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15466                    } else {
15467                        // Special handling for above-top states (persistent
15468                        // processes).  These should not bring the current process
15469                        // into the top state, since they are not on top.  Instead
15470                        // give them the best state after that.
15471                        clientProcState =
15472                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15473                    }
15474                }
15475                if (procState > clientProcState) {
15476                    procState = clientProcState;
15477                }
15478                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15479                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15480                }
15481            }
15482            // If the provider has external (non-framework) process
15483            // dependencies, ensure that its adjustment is at least
15484            // FOREGROUND_APP_ADJ.
15485            if (cpr.hasExternalProcessHandles()) {
15486                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15487                    adj = ProcessList.FOREGROUND_APP_ADJ;
15488                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15489                    app.cached = false;
15490                    app.keeping = true;
15491                    app.adjType = "provider";
15492                    app.adjTarget = cpr.name;
15493                }
15494                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15495                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15496                }
15497            }
15498        }
15499
15500        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15501            // A client of one of our services or providers is in the top state.  We
15502            // *may* want to be in the top state, but not if we are already running in
15503            // the background for some other reason.  For the decision here, we are going
15504            // to pick out a few specific states that we want to remain in when a client
15505            // is top (states that tend to be longer-term) and otherwise allow it to go
15506            // to the top state.
15507            switch (procState) {
15508                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15509                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15510                case ActivityManager.PROCESS_STATE_SERVICE:
15511                    // These all are longer-term states, so pull them up to the top
15512                    // of the background states, but not all the way to the top state.
15513                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15514                    break;
15515                default:
15516                    // Otherwise, top is a better choice, so take it.
15517                    procState = ActivityManager.PROCESS_STATE_TOP;
15518                    break;
15519            }
15520        }
15521
15522        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15523            if (app.hasClientActivities) {
15524                // This is a cached process, but with client activities.  Mark it so.
15525                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15526                app.adjType = "cch-client-act";
15527            } else if (app.treatLikeActivity) {
15528                // This is a cached process, but somebody wants us to treat it like it has
15529                // an activity, okay!
15530                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15531                app.adjType = "cch-as-act";
15532            }
15533        }
15534
15535        if (adj == ProcessList.SERVICE_ADJ) {
15536            if (doingAll) {
15537                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15538                mNewNumServiceProcs++;
15539                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15540                if (!app.serviceb) {
15541                    // This service isn't far enough down on the LRU list to
15542                    // normally be a B service, but if we are low on RAM and it
15543                    // is large we want to force it down since we would prefer to
15544                    // keep launcher over it.
15545                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15546                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15547                        app.serviceHighRam = true;
15548                        app.serviceb = true;
15549                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15550                    } else {
15551                        mNewNumAServiceProcs++;
15552                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15553                    }
15554                } else {
15555                    app.serviceHighRam = false;
15556                }
15557            }
15558            if (app.serviceb) {
15559                adj = ProcessList.SERVICE_B_ADJ;
15560            }
15561        }
15562
15563        app.curRawAdj = adj;
15564
15565        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15566        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15567        if (adj > app.maxAdj) {
15568            adj = app.maxAdj;
15569            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15570                schedGroup = Process.THREAD_GROUP_DEFAULT;
15571            }
15572        }
15573        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15574            app.keeping = true;
15575        }
15576
15577        // Do final modification to adj.  Everything we do between here and applying
15578        // the final setAdj must be done in this function, because we will also use
15579        // it when computing the final cached adj later.  Note that we don't need to
15580        // worry about this for max adj above, since max adj will always be used to
15581        // keep it out of the cached vaues.
15582        app.curAdj = app.modifyRawOomAdj(adj);
15583        app.curSchedGroup = schedGroup;
15584        app.curProcState = procState;
15585        app.foregroundActivities = foregroundActivities;
15586
15587        return app.curRawAdj;
15588    }
15589
15590    /**
15591     * Schedule PSS collection of a process.
15592     */
15593    void requestPssLocked(ProcessRecord proc, int procState) {
15594        if (mPendingPssProcesses.contains(proc)) {
15595            return;
15596        }
15597        if (mPendingPssProcesses.size() == 0) {
15598            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15599        }
15600        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15601        proc.pssProcState = procState;
15602        mPendingPssProcesses.add(proc);
15603    }
15604
15605    /**
15606     * Schedule PSS collection of all processes.
15607     */
15608    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15609        if (!always) {
15610            if (now < (mLastFullPssTime +
15611                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15612                return;
15613            }
15614        }
15615        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15616        mLastFullPssTime = now;
15617        mFullPssPending = true;
15618        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15619        mPendingPssProcesses.clear();
15620        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15621            ProcessRecord app = mLruProcesses.get(i);
15622            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15623                app.pssProcState = app.setProcState;
15624                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15625                        isSleeping(), now);
15626                mPendingPssProcesses.add(app);
15627            }
15628        }
15629        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15630    }
15631
15632    /**
15633     * Ask a given process to GC right now.
15634     */
15635    final void performAppGcLocked(ProcessRecord app) {
15636        try {
15637            app.lastRequestedGc = SystemClock.uptimeMillis();
15638            if (app.thread != null) {
15639                if (app.reportLowMemory) {
15640                    app.reportLowMemory = false;
15641                    app.thread.scheduleLowMemory();
15642                } else {
15643                    app.thread.processInBackground();
15644                }
15645            }
15646        } catch (Exception e) {
15647            // whatever.
15648        }
15649    }
15650
15651    /**
15652     * Returns true if things are idle enough to perform GCs.
15653     */
15654    private final boolean canGcNowLocked() {
15655        boolean processingBroadcasts = false;
15656        for (BroadcastQueue q : mBroadcastQueues) {
15657            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15658                processingBroadcasts = true;
15659            }
15660        }
15661        return !processingBroadcasts
15662                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15663    }
15664
15665    /**
15666     * Perform GCs on all processes that are waiting for it, but only
15667     * if things are idle.
15668     */
15669    final void performAppGcsLocked() {
15670        final int N = mProcessesToGc.size();
15671        if (N <= 0) {
15672            return;
15673        }
15674        if (canGcNowLocked()) {
15675            while (mProcessesToGc.size() > 0) {
15676                ProcessRecord proc = mProcessesToGc.remove(0);
15677                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15678                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15679                            <= SystemClock.uptimeMillis()) {
15680                        // To avoid spamming the system, we will GC processes one
15681                        // at a time, waiting a few seconds between each.
15682                        performAppGcLocked(proc);
15683                        scheduleAppGcsLocked();
15684                        return;
15685                    } else {
15686                        // It hasn't been long enough since we last GCed this
15687                        // process...  put it in the list to wait for its time.
15688                        addProcessToGcListLocked(proc);
15689                        break;
15690                    }
15691                }
15692            }
15693
15694            scheduleAppGcsLocked();
15695        }
15696    }
15697
15698    /**
15699     * If all looks good, perform GCs on all processes waiting for them.
15700     */
15701    final void performAppGcsIfAppropriateLocked() {
15702        if (canGcNowLocked()) {
15703            performAppGcsLocked();
15704            return;
15705        }
15706        // Still not idle, wait some more.
15707        scheduleAppGcsLocked();
15708    }
15709
15710    /**
15711     * Schedule the execution of all pending app GCs.
15712     */
15713    final void scheduleAppGcsLocked() {
15714        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15715
15716        if (mProcessesToGc.size() > 0) {
15717            // Schedule a GC for the time to the next process.
15718            ProcessRecord proc = mProcessesToGc.get(0);
15719            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15720
15721            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15722            long now = SystemClock.uptimeMillis();
15723            if (when < (now+GC_TIMEOUT)) {
15724                when = now + GC_TIMEOUT;
15725            }
15726            mHandler.sendMessageAtTime(msg, when);
15727        }
15728    }
15729
15730    /**
15731     * Add a process to the array of processes waiting to be GCed.  Keeps the
15732     * list in sorted order by the last GC time.  The process can't already be
15733     * on the list.
15734     */
15735    final void addProcessToGcListLocked(ProcessRecord proc) {
15736        boolean added = false;
15737        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15738            if (mProcessesToGc.get(i).lastRequestedGc <
15739                    proc.lastRequestedGc) {
15740                added = true;
15741                mProcessesToGc.add(i+1, proc);
15742                break;
15743            }
15744        }
15745        if (!added) {
15746            mProcessesToGc.add(0, proc);
15747        }
15748    }
15749
15750    /**
15751     * Set up to ask a process to GC itself.  This will either do it
15752     * immediately, or put it on the list of processes to gc the next
15753     * time things are idle.
15754     */
15755    final void scheduleAppGcLocked(ProcessRecord app) {
15756        long now = SystemClock.uptimeMillis();
15757        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15758            return;
15759        }
15760        if (!mProcessesToGc.contains(app)) {
15761            addProcessToGcListLocked(app);
15762            scheduleAppGcsLocked();
15763        }
15764    }
15765
15766    final void checkExcessivePowerUsageLocked(boolean doKills) {
15767        updateCpuStatsNow();
15768
15769        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15770        boolean doWakeKills = doKills;
15771        boolean doCpuKills = doKills;
15772        if (mLastPowerCheckRealtime == 0) {
15773            doWakeKills = false;
15774        }
15775        if (mLastPowerCheckUptime == 0) {
15776            doCpuKills = false;
15777        }
15778        if (stats.isScreenOn()) {
15779            doWakeKills = false;
15780        }
15781        final long curRealtime = SystemClock.elapsedRealtime();
15782        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15783        final long curUptime = SystemClock.uptimeMillis();
15784        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15785        mLastPowerCheckRealtime = curRealtime;
15786        mLastPowerCheckUptime = curUptime;
15787        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15788            doWakeKills = false;
15789        }
15790        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15791            doCpuKills = false;
15792        }
15793        int i = mLruProcesses.size();
15794        while (i > 0) {
15795            i--;
15796            ProcessRecord app = mLruProcesses.get(i);
15797            if (!app.keeping) {
15798                long wtime;
15799                synchronized (stats) {
15800                    wtime = stats.getProcessWakeTime(app.info.uid,
15801                            app.pid, curRealtime);
15802                }
15803                long wtimeUsed = wtime - app.lastWakeTime;
15804                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15805                if (DEBUG_POWER) {
15806                    StringBuilder sb = new StringBuilder(128);
15807                    sb.append("Wake for ");
15808                    app.toShortString(sb);
15809                    sb.append(": over ");
15810                    TimeUtils.formatDuration(realtimeSince, sb);
15811                    sb.append(" used ");
15812                    TimeUtils.formatDuration(wtimeUsed, sb);
15813                    sb.append(" (");
15814                    sb.append((wtimeUsed*100)/realtimeSince);
15815                    sb.append("%)");
15816                    Slog.i(TAG, sb.toString());
15817                    sb.setLength(0);
15818                    sb.append("CPU for ");
15819                    app.toShortString(sb);
15820                    sb.append(": over ");
15821                    TimeUtils.formatDuration(uptimeSince, sb);
15822                    sb.append(" used ");
15823                    TimeUtils.formatDuration(cputimeUsed, sb);
15824                    sb.append(" (");
15825                    sb.append((cputimeUsed*100)/uptimeSince);
15826                    sb.append("%)");
15827                    Slog.i(TAG, sb.toString());
15828                }
15829                // If a process has held a wake lock for more
15830                // than 50% of the time during this period,
15831                // that sounds bad.  Kill!
15832                if (doWakeKills && realtimeSince > 0
15833                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15834                    synchronized (stats) {
15835                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15836                                realtimeSince, wtimeUsed);
15837                    }
15838                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15839                            + " during " + realtimeSince);
15840                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15841                } else if (doCpuKills && uptimeSince > 0
15842                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15843                    synchronized (stats) {
15844                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15845                                uptimeSince, cputimeUsed);
15846                    }
15847                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15848                            + " during " + uptimeSince);
15849                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15850                } else {
15851                    app.lastWakeTime = wtime;
15852                    app.lastCpuTime = app.curCpuTime;
15853                }
15854            }
15855        }
15856    }
15857
15858    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15859            ProcessRecord TOP_APP, boolean doingAll, long now) {
15860        boolean success = true;
15861
15862        if (app.curRawAdj != app.setRawAdj) {
15863            if (wasKeeping && !app.keeping) {
15864                // This app is no longer something we want to keep.  Note
15865                // its current wake lock time to later know to kill it if
15866                // it is not behaving well.
15867                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15868                synchronized (stats) {
15869                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15870                            app.pid, SystemClock.elapsedRealtime());
15871                }
15872                app.lastCpuTime = app.curCpuTime;
15873            }
15874
15875            app.setRawAdj = app.curRawAdj;
15876        }
15877
15878        int changes = 0;
15879
15880        if (app.curAdj != app.setAdj) {
15881            ProcessList.setOomAdj(app.pid, app.curAdj);
15882            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15883                TAG, "Set " + app.pid + " " + app.processName +
15884                " adj " + app.curAdj + ": " + app.adjType);
15885            app.setAdj = app.curAdj;
15886        }
15887
15888        if (app.setSchedGroup != app.curSchedGroup) {
15889            app.setSchedGroup = app.curSchedGroup;
15890            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15891                    "Setting process group of " + app.processName
15892                    + " to " + app.curSchedGroup);
15893            if (app.waitingToKill != null &&
15894                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15895                killUnneededProcessLocked(app, app.waitingToKill);
15896                success = false;
15897            } else {
15898                if (true) {
15899                    long oldId = Binder.clearCallingIdentity();
15900                    try {
15901                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15902                    } catch (Exception e) {
15903                        Slog.w(TAG, "Failed setting process group of " + app.pid
15904                                + " to " + app.curSchedGroup);
15905                        e.printStackTrace();
15906                    } finally {
15907                        Binder.restoreCallingIdentity(oldId);
15908                    }
15909                } else {
15910                    if (app.thread != null) {
15911                        try {
15912                            app.thread.setSchedulingGroup(app.curSchedGroup);
15913                        } catch (RemoteException e) {
15914                        }
15915                    }
15916                }
15917                Process.setSwappiness(app.pid,
15918                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15919            }
15920        }
15921        if (app.repForegroundActivities != app.foregroundActivities) {
15922            app.repForegroundActivities = app.foregroundActivities;
15923            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15924        }
15925        if (app.repProcState != app.curProcState) {
15926            app.repProcState = app.curProcState;
15927            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15928            if (app.thread != null) {
15929                try {
15930                    if (false) {
15931                        //RuntimeException h = new RuntimeException("here");
15932                        Slog.i(TAG, "Sending new process state " + app.repProcState
15933                                + " to " + app /*, h*/);
15934                    }
15935                    app.thread.setProcessState(app.repProcState);
15936                } catch (RemoteException e) {
15937                }
15938            }
15939        }
15940        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15941                app.setProcState)) {
15942            app.lastStateTime = now;
15943            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15944                    isSleeping(), now);
15945            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15946                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15947                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15948                    + (app.nextPssTime-now) + ": " + app);
15949        } else {
15950            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15951                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15952                requestPssLocked(app, app.setProcState);
15953                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15954                        isSleeping(), now);
15955            } else if (false && DEBUG_PSS) {
15956                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15957            }
15958        }
15959        if (app.setProcState != app.curProcState) {
15960            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15961                    "Proc state change of " + app.processName
15962                    + " to " + app.curProcState);
15963            app.setProcState = app.curProcState;
15964            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15965                app.notCachedSinceIdle = false;
15966            }
15967            if (!doingAll) {
15968                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15969            } else {
15970                app.procStateChanged = true;
15971            }
15972        }
15973
15974        if (changes != 0) {
15975            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15976            int i = mPendingProcessChanges.size()-1;
15977            ProcessChangeItem item = null;
15978            while (i >= 0) {
15979                item = mPendingProcessChanges.get(i);
15980                if (item.pid == app.pid) {
15981                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15982                    break;
15983                }
15984                i--;
15985            }
15986            if (i < 0) {
15987                // No existing item in pending changes; need a new one.
15988                final int NA = mAvailProcessChanges.size();
15989                if (NA > 0) {
15990                    item = mAvailProcessChanges.remove(NA-1);
15991                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15992                } else {
15993                    item = new ProcessChangeItem();
15994                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15995                }
15996                item.changes = 0;
15997                item.pid = app.pid;
15998                item.uid = app.info.uid;
15999                if (mPendingProcessChanges.size() == 0) {
16000                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16001                            "*** Enqueueing dispatch processes changed!");
16002                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16003                }
16004                mPendingProcessChanges.add(item);
16005            }
16006            item.changes |= changes;
16007            item.processState = app.repProcState;
16008            item.foregroundActivities = app.repForegroundActivities;
16009            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16010                    + Integer.toHexString(System.identityHashCode(item))
16011                    + " " + app.toShortString() + ": changes=" + item.changes
16012                    + " procState=" + item.processState
16013                    + " foreground=" + item.foregroundActivities
16014                    + " type=" + app.adjType + " source=" + app.adjSource
16015                    + " target=" + app.adjTarget);
16016        }
16017
16018        return success;
16019    }
16020
16021    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16022        if (proc.thread != null && proc.baseProcessTracker != null) {
16023            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16024        }
16025    }
16026
16027    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16028            ProcessRecord TOP_APP, boolean doingAll, long now) {
16029        if (app.thread == null) {
16030            return false;
16031        }
16032
16033        final boolean wasKeeping = app.keeping;
16034
16035        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16036
16037        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16038    }
16039
16040    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16041            boolean oomAdj) {
16042        if (isForeground != proc.foregroundServices) {
16043            proc.foregroundServices = isForeground;
16044            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16045                    proc.info.uid);
16046            if (isForeground) {
16047                if (curProcs == null) {
16048                    curProcs = new ArrayList<ProcessRecord>();
16049                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16050                }
16051                if (!curProcs.contains(proc)) {
16052                    curProcs.add(proc);
16053                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16054                            proc.info.packageName, proc.info.uid);
16055                }
16056            } else {
16057                if (curProcs != null) {
16058                    if (curProcs.remove(proc)) {
16059                        mBatteryStatsService.noteEvent(
16060                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16061                                proc.info.packageName, proc.info.uid);
16062                        if (curProcs.size() <= 0) {
16063                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16064                        }
16065                    }
16066                }
16067            }
16068            if (oomAdj) {
16069                updateOomAdjLocked();
16070            }
16071        }
16072    }
16073
16074    private final ActivityRecord resumedAppLocked() {
16075        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16076        String pkg;
16077        int uid;
16078        if (act != null && !act.sleeping) {
16079            pkg = act.packageName;
16080            uid = act.info.applicationInfo.uid;
16081        } else {
16082            pkg = null;
16083            uid = -1;
16084        }
16085        // Has the UID or resumed package name changed?
16086        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16087                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16088            if (mCurResumedPackage != null) {
16089                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16090                        mCurResumedPackage, mCurResumedUid);
16091            }
16092            mCurResumedPackage = pkg;
16093            mCurResumedUid = uid;
16094            if (mCurResumedPackage != null) {
16095                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16096                        mCurResumedPackage, mCurResumedUid);
16097            }
16098        }
16099        return act;
16100    }
16101
16102    final boolean updateOomAdjLocked(ProcessRecord app) {
16103        final ActivityRecord TOP_ACT = resumedAppLocked();
16104        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16105        final boolean wasCached = app.cached;
16106
16107        mAdjSeq++;
16108
16109        // This is the desired cached adjusment we want to tell it to use.
16110        // If our app is currently cached, we know it, and that is it.  Otherwise,
16111        // we don't know it yet, and it needs to now be cached we will then
16112        // need to do a complete oom adj.
16113        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16114                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16115        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16116                SystemClock.uptimeMillis());
16117        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16118            // Changed to/from cached state, so apps after it in the LRU
16119            // list may also be changed.
16120            updateOomAdjLocked();
16121        }
16122        return success;
16123    }
16124
16125    final void updateOomAdjLocked() {
16126        final ActivityRecord TOP_ACT = resumedAppLocked();
16127        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16128        final long now = SystemClock.uptimeMillis();
16129        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16130        final int N = mLruProcesses.size();
16131
16132        if (false) {
16133            RuntimeException e = new RuntimeException();
16134            e.fillInStackTrace();
16135            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16136        }
16137
16138        mAdjSeq++;
16139        mNewNumServiceProcs = 0;
16140        mNewNumAServiceProcs = 0;
16141
16142        final int emptyProcessLimit;
16143        final int cachedProcessLimit;
16144        if (mProcessLimit <= 0) {
16145            emptyProcessLimit = cachedProcessLimit = 0;
16146        } else if (mProcessLimit == 1) {
16147            emptyProcessLimit = 1;
16148            cachedProcessLimit = 0;
16149        } else {
16150            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16151            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16152        }
16153
16154        // Let's determine how many processes we have running vs.
16155        // how many slots we have for background processes; we may want
16156        // to put multiple processes in a slot of there are enough of
16157        // them.
16158        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16159                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16160        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16161        if (numEmptyProcs > cachedProcessLimit) {
16162            // If there are more empty processes than our limit on cached
16163            // processes, then use the cached process limit for the factor.
16164            // This ensures that the really old empty processes get pushed
16165            // down to the bottom, so if we are running low on memory we will
16166            // have a better chance at keeping around more cached processes
16167            // instead of a gazillion empty processes.
16168            numEmptyProcs = cachedProcessLimit;
16169        }
16170        int emptyFactor = numEmptyProcs/numSlots;
16171        if (emptyFactor < 1) emptyFactor = 1;
16172        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16173        if (cachedFactor < 1) cachedFactor = 1;
16174        int stepCached = 0;
16175        int stepEmpty = 0;
16176        int numCached = 0;
16177        int numEmpty = 0;
16178        int numTrimming = 0;
16179
16180        mNumNonCachedProcs = 0;
16181        mNumCachedHiddenProcs = 0;
16182
16183        // First update the OOM adjustment for each of the
16184        // application processes based on their current state.
16185        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16186        int nextCachedAdj = curCachedAdj+1;
16187        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16188        int nextEmptyAdj = curEmptyAdj+2;
16189        for (int i=N-1; i>=0; i--) {
16190            ProcessRecord app = mLruProcesses.get(i);
16191            if (!app.killedByAm && app.thread != null) {
16192                app.procStateChanged = false;
16193                final boolean wasKeeping = app.keeping;
16194                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16195
16196                // If we haven't yet assigned the final cached adj
16197                // to the process, do that now.
16198                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16199                    switch (app.curProcState) {
16200                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16201                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16202                            // This process is a cached process holding activities...
16203                            // assign it the next cached value for that type, and then
16204                            // step that cached level.
16205                            app.curRawAdj = curCachedAdj;
16206                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16207                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16208                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16209                                    + ")");
16210                            if (curCachedAdj != nextCachedAdj) {
16211                                stepCached++;
16212                                if (stepCached >= cachedFactor) {
16213                                    stepCached = 0;
16214                                    curCachedAdj = nextCachedAdj;
16215                                    nextCachedAdj += 2;
16216                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16217                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16218                                    }
16219                                }
16220                            }
16221                            break;
16222                        default:
16223                            // For everything else, assign next empty cached process
16224                            // level and bump that up.  Note that this means that
16225                            // long-running services that have dropped down to the
16226                            // cached level will be treated as empty (since their process
16227                            // state is still as a service), which is what we want.
16228                            app.curRawAdj = curEmptyAdj;
16229                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16230                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16231                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16232                                    + ")");
16233                            if (curEmptyAdj != nextEmptyAdj) {
16234                                stepEmpty++;
16235                                if (stepEmpty >= emptyFactor) {
16236                                    stepEmpty = 0;
16237                                    curEmptyAdj = nextEmptyAdj;
16238                                    nextEmptyAdj += 2;
16239                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16240                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16241                                    }
16242                                }
16243                            }
16244                            break;
16245                    }
16246                }
16247
16248                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16249
16250                // Count the number of process types.
16251                switch (app.curProcState) {
16252                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16253                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16254                        mNumCachedHiddenProcs++;
16255                        numCached++;
16256                        if (numCached > cachedProcessLimit) {
16257                            killUnneededProcessLocked(app, "cached #" + numCached);
16258                        }
16259                        break;
16260                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16261                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16262                                && app.lastActivityTime < oldTime) {
16263                            killUnneededProcessLocked(app, "empty for "
16264                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16265                                    / 1000) + "s");
16266                        } else {
16267                            numEmpty++;
16268                            if (numEmpty > emptyProcessLimit) {
16269                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16270                            }
16271                        }
16272                        break;
16273                    default:
16274                        mNumNonCachedProcs++;
16275                        break;
16276                }
16277
16278                if (app.isolated && app.services.size() <= 0) {
16279                    // If this is an isolated process, and there are no
16280                    // services running in it, then the process is no longer
16281                    // needed.  We agressively kill these because we can by
16282                    // definition not re-use the same process again, and it is
16283                    // good to avoid having whatever code was running in them
16284                    // left sitting around after no longer needed.
16285                    killUnneededProcessLocked(app, "isolated not needed");
16286                }
16287
16288                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16289                        && !app.killedByAm) {
16290                    numTrimming++;
16291                }
16292            }
16293        }
16294
16295        mNumServiceProcs = mNewNumServiceProcs;
16296
16297        // Now determine the memory trimming level of background processes.
16298        // Unfortunately we need to start at the back of the list to do this
16299        // properly.  We only do this if the number of background apps we
16300        // are managing to keep around is less than half the maximum we desire;
16301        // if we are keeping a good number around, we'll let them use whatever
16302        // memory they want.
16303        final int numCachedAndEmpty = numCached + numEmpty;
16304        int memFactor;
16305        if (numCached <= ProcessList.TRIM_CACHED_APPS
16306                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16307            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16308                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16309            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16310                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16311            } else {
16312                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16313            }
16314        } else {
16315            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16316        }
16317        // We always allow the memory level to go up (better).  We only allow it to go
16318        // down if we are in a state where that is allowed, *and* the total number of processes
16319        // has gone down since last time.
16320        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16321                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16322                + " last=" + mLastNumProcesses);
16323        if (memFactor > mLastMemoryLevel) {
16324            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16325                memFactor = mLastMemoryLevel;
16326                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16327            }
16328        }
16329        mLastMemoryLevel = memFactor;
16330        mLastNumProcesses = mLruProcesses.size();
16331        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16332        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16333        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16334            if (mLowRamStartTime == 0) {
16335                mLowRamStartTime = now;
16336            }
16337            int step = 0;
16338            int fgTrimLevel;
16339            switch (memFactor) {
16340                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16341                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16342                    break;
16343                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16344                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16345                    break;
16346                default:
16347                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16348                    break;
16349            }
16350            int factor = numTrimming/3;
16351            int minFactor = 2;
16352            if (mHomeProcess != null) minFactor++;
16353            if (mPreviousProcess != null) minFactor++;
16354            if (factor < minFactor) factor = minFactor;
16355            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16356            for (int i=N-1; i>=0; i--) {
16357                ProcessRecord app = mLruProcesses.get(i);
16358                if (allChanged || app.procStateChanged) {
16359                    setProcessTrackerState(app, trackerMemFactor, now);
16360                    app.procStateChanged = false;
16361                }
16362                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16363                        && !app.killedByAm) {
16364                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16365                        try {
16366                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16367                                    "Trimming memory of " + app.processName
16368                                    + " to " + curLevel);
16369                            app.thread.scheduleTrimMemory(curLevel);
16370                        } catch (RemoteException e) {
16371                        }
16372                        if (false) {
16373                            // For now we won't do this; our memory trimming seems
16374                            // to be good enough at this point that destroying
16375                            // activities causes more harm than good.
16376                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16377                                    && app != mHomeProcess && app != mPreviousProcess) {
16378                                // Need to do this on its own message because the stack may not
16379                                // be in a consistent state at this point.
16380                                // For these apps we will also finish their activities
16381                                // to help them free memory.
16382                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16383                            }
16384                        }
16385                    }
16386                    app.trimMemoryLevel = curLevel;
16387                    step++;
16388                    if (step >= factor) {
16389                        step = 0;
16390                        switch (curLevel) {
16391                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16392                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16393                                break;
16394                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16395                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16396                                break;
16397                        }
16398                    }
16399                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16400                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16401                            && app.thread != null) {
16402                        try {
16403                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16404                                    "Trimming memory of heavy-weight " + app.processName
16405                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16406                            app.thread.scheduleTrimMemory(
16407                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16408                        } catch (RemoteException e) {
16409                        }
16410                    }
16411                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16412                } else {
16413                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16414                            || app.systemNoUi) && app.pendingUiClean) {
16415                        // If this application is now in the background and it
16416                        // had done UI, then give it the special trim level to
16417                        // have it free UI resources.
16418                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16419                        if (app.trimMemoryLevel < level && app.thread != null) {
16420                            try {
16421                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16422                                        "Trimming memory of bg-ui " + app.processName
16423                                        + " to " + level);
16424                                app.thread.scheduleTrimMemory(level);
16425                            } catch (RemoteException e) {
16426                            }
16427                        }
16428                        app.pendingUiClean = false;
16429                    }
16430                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16431                        try {
16432                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16433                                    "Trimming memory of fg " + app.processName
16434                                    + " to " + fgTrimLevel);
16435                            app.thread.scheduleTrimMemory(fgTrimLevel);
16436                        } catch (RemoteException e) {
16437                        }
16438                    }
16439                    app.trimMemoryLevel = fgTrimLevel;
16440                }
16441            }
16442        } else {
16443            if (mLowRamStartTime != 0) {
16444                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16445                mLowRamStartTime = 0;
16446            }
16447            for (int i=N-1; i>=0; i--) {
16448                ProcessRecord app = mLruProcesses.get(i);
16449                if (allChanged || app.procStateChanged) {
16450                    setProcessTrackerState(app, trackerMemFactor, now);
16451                    app.procStateChanged = false;
16452                }
16453                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16454                        || app.systemNoUi) && app.pendingUiClean) {
16455                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16456                            && app.thread != null) {
16457                        try {
16458                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16459                                    "Trimming memory of ui hidden " + app.processName
16460                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16461                            app.thread.scheduleTrimMemory(
16462                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16463                        } catch (RemoteException e) {
16464                        }
16465                    }
16466                    app.pendingUiClean = false;
16467                }
16468                app.trimMemoryLevel = 0;
16469            }
16470        }
16471
16472        if (mAlwaysFinishActivities) {
16473            // Need to do this on its own message because the stack may not
16474            // be in a consistent state at this point.
16475            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16476        }
16477
16478        if (allChanged) {
16479            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16480        }
16481
16482        if (mProcessStats.shouldWriteNowLocked(now)) {
16483            mHandler.post(new Runnable() {
16484                @Override public void run() {
16485                    synchronized (ActivityManagerService.this) {
16486                        mProcessStats.writeStateAsyncLocked();
16487                    }
16488                }
16489            });
16490        }
16491
16492        if (DEBUG_OOM_ADJ) {
16493            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16494        }
16495    }
16496
16497    final void trimApplications() {
16498        synchronized (this) {
16499            int i;
16500
16501            // First remove any unused application processes whose package
16502            // has been removed.
16503            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16504                final ProcessRecord app = mRemovedProcesses.get(i);
16505                if (app.activities.size() == 0
16506                        && app.curReceiver == null && app.services.size() == 0) {
16507                    Slog.i(
16508                        TAG, "Exiting empty application process "
16509                        + app.processName + " ("
16510                        + (app.thread != null ? app.thread.asBinder() : null)
16511                        + ")\n");
16512                    if (app.pid > 0 && app.pid != MY_PID) {
16513                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16514                                app.processName, app.setAdj, "empty");
16515                        app.killedByAm = true;
16516                        Process.killProcessQuiet(app.pid);
16517                    } else {
16518                        try {
16519                            app.thread.scheduleExit();
16520                        } catch (Exception e) {
16521                            // Ignore exceptions.
16522                        }
16523                    }
16524                    cleanUpApplicationRecordLocked(app, false, true, -1);
16525                    mRemovedProcesses.remove(i);
16526
16527                    if (app.persistent) {
16528                        if (app.persistent) {
16529                            addAppLocked(app.info, false, null /* ABI override */);
16530                        }
16531                    }
16532                }
16533            }
16534
16535            // Now update the oom adj for all processes.
16536            updateOomAdjLocked();
16537        }
16538    }
16539
16540    /** This method sends the specified signal to each of the persistent apps */
16541    public void signalPersistentProcesses(int sig) throws RemoteException {
16542        if (sig != Process.SIGNAL_USR1) {
16543            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16544        }
16545
16546        synchronized (this) {
16547            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16548                    != PackageManager.PERMISSION_GRANTED) {
16549                throw new SecurityException("Requires permission "
16550                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16551            }
16552
16553            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16554                ProcessRecord r = mLruProcesses.get(i);
16555                if (r.thread != null && r.persistent) {
16556                    Process.sendSignal(r.pid, sig);
16557                }
16558            }
16559        }
16560    }
16561
16562    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16563        if (proc == null || proc == mProfileProc) {
16564            proc = mProfileProc;
16565            path = mProfileFile;
16566            profileType = mProfileType;
16567            clearProfilerLocked();
16568        }
16569        if (proc == null) {
16570            return;
16571        }
16572        try {
16573            proc.thread.profilerControl(false, path, null, profileType);
16574        } catch (RemoteException e) {
16575            throw new IllegalStateException("Process disappeared");
16576        }
16577    }
16578
16579    private void clearProfilerLocked() {
16580        if (mProfileFd != null) {
16581            try {
16582                mProfileFd.close();
16583            } catch (IOException e) {
16584            }
16585        }
16586        mProfileApp = null;
16587        mProfileProc = null;
16588        mProfileFile = null;
16589        mProfileType = 0;
16590        mAutoStopProfiler = false;
16591    }
16592
16593    public boolean profileControl(String process, int userId, boolean start,
16594            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16595
16596        try {
16597            synchronized (this) {
16598                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16599                // its own permission.
16600                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16601                        != PackageManager.PERMISSION_GRANTED) {
16602                    throw new SecurityException("Requires permission "
16603                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16604                }
16605
16606                if (start && fd == null) {
16607                    throw new IllegalArgumentException("null fd");
16608                }
16609
16610                ProcessRecord proc = null;
16611                if (process != null) {
16612                    proc = findProcessLocked(process, userId, "profileControl");
16613                }
16614
16615                if (start && (proc == null || proc.thread == null)) {
16616                    throw new IllegalArgumentException("Unknown process: " + process);
16617                }
16618
16619                if (start) {
16620                    stopProfilerLocked(null, null, 0);
16621                    setProfileApp(proc.info, proc.processName, path, fd, false);
16622                    mProfileProc = proc;
16623                    mProfileType = profileType;
16624                    try {
16625                        fd = fd.dup();
16626                    } catch (IOException e) {
16627                        fd = null;
16628                    }
16629                    proc.thread.profilerControl(start, path, fd, profileType);
16630                    fd = null;
16631                    mProfileFd = null;
16632                } else {
16633                    stopProfilerLocked(proc, path, profileType);
16634                    if (fd != null) {
16635                        try {
16636                            fd.close();
16637                        } catch (IOException e) {
16638                        }
16639                    }
16640                }
16641
16642                return true;
16643            }
16644        } catch (RemoteException e) {
16645            throw new IllegalStateException("Process disappeared");
16646        } finally {
16647            if (fd != null) {
16648                try {
16649                    fd.close();
16650                } catch (IOException e) {
16651                }
16652            }
16653        }
16654    }
16655
16656    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16657        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16658                userId, true, true, callName, null);
16659        ProcessRecord proc = null;
16660        try {
16661            int pid = Integer.parseInt(process);
16662            synchronized (mPidsSelfLocked) {
16663                proc = mPidsSelfLocked.get(pid);
16664            }
16665        } catch (NumberFormatException e) {
16666        }
16667
16668        if (proc == null) {
16669            ArrayMap<String, SparseArray<ProcessRecord>> all
16670                    = mProcessNames.getMap();
16671            SparseArray<ProcessRecord> procs = all.get(process);
16672            if (procs != null && procs.size() > 0) {
16673                proc = procs.valueAt(0);
16674                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16675                    for (int i=1; i<procs.size(); i++) {
16676                        ProcessRecord thisProc = procs.valueAt(i);
16677                        if (thisProc.userId == userId) {
16678                            proc = thisProc;
16679                            break;
16680                        }
16681                    }
16682                }
16683            }
16684        }
16685
16686        return proc;
16687    }
16688
16689    public boolean dumpHeap(String process, int userId, boolean managed,
16690            String path, ParcelFileDescriptor fd) throws RemoteException {
16691
16692        try {
16693            synchronized (this) {
16694                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16695                // its own permission (same as profileControl).
16696                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16697                        != PackageManager.PERMISSION_GRANTED) {
16698                    throw new SecurityException("Requires permission "
16699                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16700                }
16701
16702                if (fd == null) {
16703                    throw new IllegalArgumentException("null fd");
16704                }
16705
16706                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16707                if (proc == null || proc.thread == null) {
16708                    throw new IllegalArgumentException("Unknown process: " + process);
16709                }
16710
16711                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16712                if (!isDebuggable) {
16713                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16714                        throw new SecurityException("Process not debuggable: " + proc);
16715                    }
16716                }
16717
16718                proc.thread.dumpHeap(managed, path, fd);
16719                fd = null;
16720                return true;
16721            }
16722        } catch (RemoteException e) {
16723            throw new IllegalStateException("Process disappeared");
16724        } finally {
16725            if (fd != null) {
16726                try {
16727                    fd.close();
16728                } catch (IOException e) {
16729                }
16730            }
16731        }
16732    }
16733
16734    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16735    public void monitor() {
16736        synchronized (this) { }
16737    }
16738
16739    void onCoreSettingsChange(Bundle settings) {
16740        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16741            ProcessRecord processRecord = mLruProcesses.get(i);
16742            try {
16743                if (processRecord.thread != null) {
16744                    processRecord.thread.setCoreSettings(settings);
16745                }
16746            } catch (RemoteException re) {
16747                /* ignore */
16748            }
16749        }
16750    }
16751
16752    // Multi-user methods
16753
16754    /**
16755     * Start user, if its not already running, but don't bring it to foreground.
16756     */
16757    @Override
16758    public boolean startUserInBackground(final int userId) {
16759        return startUser(userId, /* foreground */ false);
16760    }
16761
16762    /**
16763     * Refreshes the list of users related to the current user when either a
16764     * user switch happens or when a new related user is started in the
16765     * background.
16766     */
16767    private void updateCurrentProfileIdsLocked() {
16768        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16769                mCurrentUserId, false /* enabledOnly */);
16770        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16771        for (int i = 0; i < currentProfileIds.length; i++) {
16772            currentProfileIds[i] = profiles.get(i).id;
16773        }
16774        mCurrentProfileIds = currentProfileIds;
16775    }
16776
16777    private Set getProfileIdsLocked(int userId) {
16778        Set userIds = new HashSet<Integer>();
16779        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16780                userId, false /* enabledOnly */);
16781        for (UserInfo user : profiles) {
16782            userIds.add(Integer.valueOf(user.id));
16783        }
16784        return userIds;
16785    }
16786
16787    @Override
16788    public boolean switchUser(final int userId) {
16789        return startUser(userId, /* foregound */ true);
16790    }
16791
16792    private boolean startUser(final int userId, boolean foreground) {
16793        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16794                != PackageManager.PERMISSION_GRANTED) {
16795            String msg = "Permission Denial: switchUser() from pid="
16796                    + Binder.getCallingPid()
16797                    + ", uid=" + Binder.getCallingUid()
16798                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16799            Slog.w(TAG, msg);
16800            throw new SecurityException(msg);
16801        }
16802
16803        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16804
16805        final long ident = Binder.clearCallingIdentity();
16806        try {
16807            synchronized (this) {
16808                final int oldUserId = mCurrentUserId;
16809                if (oldUserId == userId) {
16810                    return true;
16811                }
16812
16813                mStackSupervisor.setLockTaskModeLocked(null, false);
16814
16815                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16816                if (userInfo == null) {
16817                    Slog.w(TAG, "No user info for user #" + userId);
16818                    return false;
16819                }
16820
16821                if (foreground) {
16822                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16823                            R.anim.screen_user_enter);
16824                }
16825
16826                boolean needStart = false;
16827
16828                // If the user we are switching to is not currently started, then
16829                // we need to start it now.
16830                if (mStartedUsers.get(userId) == null) {
16831                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16832                    updateStartedUserArrayLocked();
16833                    needStart = true;
16834                }
16835
16836                final Integer userIdInt = Integer.valueOf(userId);
16837                mUserLru.remove(userIdInt);
16838                mUserLru.add(userIdInt);
16839
16840                if (foreground) {
16841                    mCurrentUserId = userId;
16842                    updateCurrentProfileIdsLocked();
16843                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16844                    // Once the internal notion of the active user has switched, we lock the device
16845                    // with the option to show the user switcher on the keyguard.
16846                    mWindowManager.lockNow(null);
16847                } else {
16848                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16849                    updateCurrentProfileIdsLocked();
16850                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16851                    mUserLru.remove(currentUserIdInt);
16852                    mUserLru.add(currentUserIdInt);
16853                }
16854
16855                final UserStartedState uss = mStartedUsers.get(userId);
16856
16857                // Make sure user is in the started state.  If it is currently
16858                // stopping, we need to knock that off.
16859                if (uss.mState == UserStartedState.STATE_STOPPING) {
16860                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16861                    // so we can just fairly silently bring the user back from
16862                    // the almost-dead.
16863                    uss.mState = UserStartedState.STATE_RUNNING;
16864                    updateStartedUserArrayLocked();
16865                    needStart = true;
16866                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16867                    // This means ACTION_SHUTDOWN has been sent, so we will
16868                    // need to treat this as a new boot of the user.
16869                    uss.mState = UserStartedState.STATE_BOOTING;
16870                    updateStartedUserArrayLocked();
16871                    needStart = true;
16872                }
16873
16874                if (uss.mState == UserStartedState.STATE_BOOTING) {
16875                    // Booting up a new user, need to tell system services about it.
16876                    // Note that this is on the same handler as scheduling of broadcasts,
16877                    // which is important because it needs to go first.
16878                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16879                }
16880
16881                if (foreground) {
16882                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16883                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16884                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16885                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16886                            oldUserId, userId, uss));
16887                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16888                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16889                }
16890
16891                if (needStart) {
16892                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16893                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16894                            | Intent.FLAG_RECEIVER_FOREGROUND);
16895                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16896                    broadcastIntentLocked(null, null, intent,
16897                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16898                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16899                }
16900
16901                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16902                    if (userId != UserHandle.USER_OWNER) {
16903                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16904                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16905                        broadcastIntentLocked(null, null, intent, null,
16906                                new IIntentReceiver.Stub() {
16907                                    public void performReceive(Intent intent, int resultCode,
16908                                            String data, Bundle extras, boolean ordered,
16909                                            boolean sticky, int sendingUser) {
16910                                        userInitialized(uss, userId);
16911                                    }
16912                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16913                                true, false, MY_PID, Process.SYSTEM_UID,
16914                                userId);
16915                        uss.initializing = true;
16916                    } else {
16917                        getUserManagerLocked().makeInitialized(userInfo.id);
16918                    }
16919                }
16920
16921                if (foreground) {
16922                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16923                    if (homeInFront) {
16924                        startHomeActivityLocked(userId);
16925                    } else {
16926                        mStackSupervisor.resumeTopActivitiesLocked();
16927                    }
16928                    EventLogTags.writeAmSwitchUser(userId);
16929                    getUserManagerLocked().userForeground(userId);
16930                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16931                } else {
16932                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16933                }
16934
16935                if (needStart) {
16936                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16937                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16938                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16939                    broadcastIntentLocked(null, null, intent,
16940                            null, new IIntentReceiver.Stub() {
16941                                @Override
16942                                public void performReceive(Intent intent, int resultCode, String data,
16943                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16944                                        throws RemoteException {
16945                                }
16946                            }, 0, null, null,
16947                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16948                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16949                }
16950            }
16951        } finally {
16952            Binder.restoreCallingIdentity(ident);
16953        }
16954
16955        return true;
16956    }
16957
16958    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16959        long ident = Binder.clearCallingIdentity();
16960        try {
16961            Intent intent;
16962            if (oldUserId >= 0) {
16963                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16964                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16965                        | Intent.FLAG_RECEIVER_FOREGROUND);
16966                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16967                broadcastIntentLocked(null, null, intent,
16968                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16969                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16970            }
16971            if (newUserId >= 0) {
16972                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16973                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16974                        | Intent.FLAG_RECEIVER_FOREGROUND);
16975                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16976                broadcastIntentLocked(null, null, intent,
16977                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16978                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16979                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16980                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16981                        | Intent.FLAG_RECEIVER_FOREGROUND);
16982                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16983                broadcastIntentLocked(null, null, intent,
16984                        null, null, 0, null, null,
16985                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16986                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16987            }
16988        } finally {
16989            Binder.restoreCallingIdentity(ident);
16990        }
16991    }
16992
16993    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16994            final int newUserId) {
16995        final int N = mUserSwitchObservers.beginBroadcast();
16996        if (N > 0) {
16997            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16998                int mCount = 0;
16999                @Override
17000                public void sendResult(Bundle data) throws RemoteException {
17001                    synchronized (ActivityManagerService.this) {
17002                        if (mCurUserSwitchCallback == this) {
17003                            mCount++;
17004                            if (mCount == N) {
17005                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17006                            }
17007                        }
17008                    }
17009                }
17010            };
17011            synchronized (this) {
17012                uss.switching = true;
17013                mCurUserSwitchCallback = callback;
17014            }
17015            for (int i=0; i<N; i++) {
17016                try {
17017                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17018                            newUserId, callback);
17019                } catch (RemoteException e) {
17020                }
17021            }
17022        } else {
17023            synchronized (this) {
17024                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17025            }
17026        }
17027        mUserSwitchObservers.finishBroadcast();
17028    }
17029
17030    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17031        synchronized (this) {
17032            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17033            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17034        }
17035    }
17036
17037    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17038        mCurUserSwitchCallback = null;
17039        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17040        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17041                oldUserId, newUserId, uss));
17042    }
17043
17044    void userInitialized(UserStartedState uss, int newUserId) {
17045        completeSwitchAndInitalize(uss, newUserId, true, false);
17046    }
17047
17048    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17049        completeSwitchAndInitalize(uss, newUserId, false, true);
17050    }
17051
17052    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17053            boolean clearInitializing, boolean clearSwitching) {
17054        boolean unfrozen = false;
17055        synchronized (this) {
17056            if (clearInitializing) {
17057                uss.initializing = false;
17058                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17059            }
17060            if (clearSwitching) {
17061                uss.switching = false;
17062            }
17063            if (!uss.switching && !uss.initializing) {
17064                mWindowManager.stopFreezingScreen();
17065                unfrozen = true;
17066            }
17067        }
17068        if (unfrozen) {
17069            final int N = mUserSwitchObservers.beginBroadcast();
17070            for (int i=0; i<N; i++) {
17071                try {
17072                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17073                } catch (RemoteException e) {
17074                }
17075            }
17076            mUserSwitchObservers.finishBroadcast();
17077        }
17078    }
17079
17080    void scheduleStartProfilesLocked() {
17081        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17082            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17083                    DateUtils.SECOND_IN_MILLIS);
17084        }
17085    }
17086
17087    void startProfilesLocked() {
17088        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17089        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17090                mCurrentUserId, false /* enabledOnly */);
17091        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17092        for (UserInfo user : profiles) {
17093            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17094                    && user.id != mCurrentUserId) {
17095                toStart.add(user);
17096            }
17097        }
17098        final int n = toStart.size();
17099        int i = 0;
17100        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17101            startUserInBackground(toStart.get(i).id);
17102        }
17103        if (i < n) {
17104            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17105        }
17106    }
17107
17108    void finishUserBoot(UserStartedState uss) {
17109        synchronized (this) {
17110            if (uss.mState == UserStartedState.STATE_BOOTING
17111                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17112                uss.mState = UserStartedState.STATE_RUNNING;
17113                final int userId = uss.mHandle.getIdentifier();
17114                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17115                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17116                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17117                broadcastIntentLocked(null, null, intent,
17118                        null, null, 0, null, null,
17119                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17120                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17121            }
17122        }
17123    }
17124
17125    void finishUserSwitch(UserStartedState uss) {
17126        synchronized (this) {
17127            finishUserBoot(uss);
17128
17129            startProfilesLocked();
17130
17131            int num = mUserLru.size();
17132            int i = 0;
17133            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17134                Integer oldUserId = mUserLru.get(i);
17135                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17136                if (oldUss == null) {
17137                    // Shouldn't happen, but be sane if it does.
17138                    mUserLru.remove(i);
17139                    num--;
17140                    continue;
17141                }
17142                if (oldUss.mState == UserStartedState.STATE_STOPPING
17143                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17144                    // This user is already stopping, doesn't count.
17145                    num--;
17146                    i++;
17147                    continue;
17148                }
17149                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17150                    // Owner and current can't be stopped, but count as running.
17151                    i++;
17152                    continue;
17153                }
17154                // This is a user to be stopped.
17155                stopUserLocked(oldUserId, null);
17156                num--;
17157                i++;
17158            }
17159        }
17160    }
17161
17162    @Override
17163    public int stopUser(final int userId, final IStopUserCallback callback) {
17164        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17165                != PackageManager.PERMISSION_GRANTED) {
17166            String msg = "Permission Denial: switchUser() from pid="
17167                    + Binder.getCallingPid()
17168                    + ", uid=" + Binder.getCallingUid()
17169                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17170            Slog.w(TAG, msg);
17171            throw new SecurityException(msg);
17172        }
17173        if (userId <= 0) {
17174            throw new IllegalArgumentException("Can't stop primary user " + userId);
17175        }
17176        synchronized (this) {
17177            return stopUserLocked(userId, callback);
17178        }
17179    }
17180
17181    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17182        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17183        if (mCurrentUserId == userId) {
17184            return ActivityManager.USER_OP_IS_CURRENT;
17185        }
17186
17187        final UserStartedState uss = mStartedUsers.get(userId);
17188        if (uss == null) {
17189            // User is not started, nothing to do...  but we do need to
17190            // callback if requested.
17191            if (callback != null) {
17192                mHandler.post(new Runnable() {
17193                    @Override
17194                    public void run() {
17195                        try {
17196                            callback.userStopped(userId);
17197                        } catch (RemoteException e) {
17198                        }
17199                    }
17200                });
17201            }
17202            return ActivityManager.USER_OP_SUCCESS;
17203        }
17204
17205        if (callback != null) {
17206            uss.mStopCallbacks.add(callback);
17207        }
17208
17209        if (uss.mState != UserStartedState.STATE_STOPPING
17210                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17211            uss.mState = UserStartedState.STATE_STOPPING;
17212            updateStartedUserArrayLocked();
17213
17214            long ident = Binder.clearCallingIdentity();
17215            try {
17216                // We are going to broadcast ACTION_USER_STOPPING and then
17217                // once that is done send a final ACTION_SHUTDOWN and then
17218                // stop the user.
17219                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17220                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17221                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17222                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17223                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17224                // This is the result receiver for the final shutdown broadcast.
17225                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17226                    @Override
17227                    public void performReceive(Intent intent, int resultCode, String data,
17228                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17229                        finishUserStop(uss);
17230                    }
17231                };
17232                // This is the result receiver for the initial stopping broadcast.
17233                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17234                    @Override
17235                    public void performReceive(Intent intent, int resultCode, String data,
17236                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17237                        // On to the next.
17238                        synchronized (ActivityManagerService.this) {
17239                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17240                                // Whoops, we are being started back up.  Abort, abort!
17241                                return;
17242                            }
17243                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17244                        }
17245                        mSystemServiceManager.stopUser(userId);
17246                        broadcastIntentLocked(null, null, shutdownIntent,
17247                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17248                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17249                    }
17250                };
17251                // Kick things off.
17252                broadcastIntentLocked(null, null, stoppingIntent,
17253                        null, stoppingReceiver, 0, null, null,
17254                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17255                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17256            } finally {
17257                Binder.restoreCallingIdentity(ident);
17258            }
17259        }
17260
17261        return ActivityManager.USER_OP_SUCCESS;
17262    }
17263
17264    void finishUserStop(UserStartedState uss) {
17265        final int userId = uss.mHandle.getIdentifier();
17266        boolean stopped;
17267        ArrayList<IStopUserCallback> callbacks;
17268        synchronized (this) {
17269            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17270            if (mStartedUsers.get(userId) != uss) {
17271                stopped = false;
17272            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17273                stopped = false;
17274            } else {
17275                stopped = true;
17276                // User can no longer run.
17277                mStartedUsers.remove(userId);
17278                mUserLru.remove(Integer.valueOf(userId));
17279                updateStartedUserArrayLocked();
17280
17281                // Clean up all state and processes associated with the user.
17282                // Kill all the processes for the user.
17283                forceStopUserLocked(userId, "finish user");
17284            }
17285        }
17286
17287        for (int i=0; i<callbacks.size(); i++) {
17288            try {
17289                if (stopped) callbacks.get(i).userStopped(userId);
17290                else callbacks.get(i).userStopAborted(userId);
17291            } catch (RemoteException e) {
17292            }
17293        }
17294
17295        if (stopped) {
17296            mSystemServiceManager.cleanupUser(userId);
17297            synchronized (this) {
17298                mStackSupervisor.removeUserLocked(userId);
17299            }
17300        }
17301    }
17302
17303    @Override
17304    public UserInfo getCurrentUser() {
17305        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17306                != PackageManager.PERMISSION_GRANTED) && (
17307                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17308                != PackageManager.PERMISSION_GRANTED)) {
17309            String msg = "Permission Denial: getCurrentUser() from pid="
17310                    + Binder.getCallingPid()
17311                    + ", uid=" + Binder.getCallingUid()
17312                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17313            Slog.w(TAG, msg);
17314            throw new SecurityException(msg);
17315        }
17316        synchronized (this) {
17317            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17318        }
17319    }
17320
17321    int getCurrentUserIdLocked() {
17322        return mCurrentUserId;
17323    }
17324
17325    @Override
17326    public boolean isUserRunning(int userId, boolean orStopped) {
17327        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17328                != PackageManager.PERMISSION_GRANTED) {
17329            String msg = "Permission Denial: isUserRunning() from pid="
17330                    + Binder.getCallingPid()
17331                    + ", uid=" + Binder.getCallingUid()
17332                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17333            Slog.w(TAG, msg);
17334            throw new SecurityException(msg);
17335        }
17336        synchronized (this) {
17337            return isUserRunningLocked(userId, orStopped);
17338        }
17339    }
17340
17341    boolean isUserRunningLocked(int userId, boolean orStopped) {
17342        UserStartedState state = mStartedUsers.get(userId);
17343        if (state == null) {
17344            return false;
17345        }
17346        if (orStopped) {
17347            return true;
17348        }
17349        return state.mState != UserStartedState.STATE_STOPPING
17350                && state.mState != UserStartedState.STATE_SHUTDOWN;
17351    }
17352
17353    @Override
17354    public int[] getRunningUserIds() {
17355        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17356                != PackageManager.PERMISSION_GRANTED) {
17357            String msg = "Permission Denial: isUserRunning() from pid="
17358                    + Binder.getCallingPid()
17359                    + ", uid=" + Binder.getCallingUid()
17360                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17361            Slog.w(TAG, msg);
17362            throw new SecurityException(msg);
17363        }
17364        synchronized (this) {
17365            return mStartedUserArray;
17366        }
17367    }
17368
17369    private void updateStartedUserArrayLocked() {
17370        int num = 0;
17371        for (int i=0; i<mStartedUsers.size();  i++) {
17372            UserStartedState uss = mStartedUsers.valueAt(i);
17373            // This list does not include stopping users.
17374            if (uss.mState != UserStartedState.STATE_STOPPING
17375                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17376                num++;
17377            }
17378        }
17379        mStartedUserArray = new int[num];
17380        num = 0;
17381        for (int i=0; i<mStartedUsers.size();  i++) {
17382            UserStartedState uss = mStartedUsers.valueAt(i);
17383            if (uss.mState != UserStartedState.STATE_STOPPING
17384                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17385                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17386                num++;
17387            }
17388        }
17389    }
17390
17391    @Override
17392    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17393        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17394                != PackageManager.PERMISSION_GRANTED) {
17395            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17396                    + Binder.getCallingPid()
17397                    + ", uid=" + Binder.getCallingUid()
17398                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17399            Slog.w(TAG, msg);
17400            throw new SecurityException(msg);
17401        }
17402
17403        mUserSwitchObservers.register(observer);
17404    }
17405
17406    @Override
17407    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17408        mUserSwitchObservers.unregister(observer);
17409    }
17410
17411    private boolean userExists(int userId) {
17412        if (userId == 0) {
17413            return true;
17414        }
17415        UserManagerService ums = getUserManagerLocked();
17416        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17417    }
17418
17419    int[] getUsersLocked() {
17420        UserManagerService ums = getUserManagerLocked();
17421        return ums != null ? ums.getUserIds() : new int[] { 0 };
17422    }
17423
17424    UserManagerService getUserManagerLocked() {
17425        if (mUserManager == null) {
17426            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17427            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17428        }
17429        return mUserManager;
17430    }
17431
17432    private int applyUserId(int uid, int userId) {
17433        return UserHandle.getUid(userId, uid);
17434    }
17435
17436    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17437        if (info == null) return null;
17438        ApplicationInfo newInfo = new ApplicationInfo(info);
17439        newInfo.uid = applyUserId(info.uid, userId);
17440        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17441                + info.packageName;
17442        return newInfo;
17443    }
17444
17445    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17446        if (aInfo == null
17447                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17448            return aInfo;
17449        }
17450
17451        ActivityInfo info = new ActivityInfo(aInfo);
17452        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17453        return info;
17454    }
17455
17456    private final class LocalService extends ActivityManagerInternal {
17457        @Override
17458        public void goingToSleep() {
17459            ActivityManagerService.this.goingToSleep();
17460        }
17461
17462        @Override
17463        public void wakingUp() {
17464            ActivityManagerService.this.wakingUp();
17465        }
17466    }
17467
17468    /**
17469     * An implementation of IAppTask, that allows an app to manage its own tasks via
17470     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17471     * only the process that calls getAppTasks() can call the AppTask methods.
17472     */
17473    class AppTaskImpl extends IAppTask.Stub {
17474        private int mTaskId;
17475        private int mCallingUid;
17476
17477        public AppTaskImpl(int taskId, int callingUid) {
17478            mTaskId = taskId;
17479            mCallingUid = callingUid;
17480        }
17481
17482        @Override
17483        public void finishAndRemoveTask() {
17484            // Ensure that we are called from the same process that created this AppTask
17485            if (mCallingUid != Binder.getCallingUid()) {
17486                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17487                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17488                return;
17489            }
17490
17491            synchronized (ActivityManagerService.this) {
17492                long origId = Binder.clearCallingIdentity();
17493                try {
17494                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17495                    if (tr != null) {
17496                        // Only kill the process if we are not a new document
17497                        int flags = tr.getBaseIntent().getFlags();
17498                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17499                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17500                        removeTaskByIdLocked(mTaskId,
17501                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17502                    }
17503                } finally {
17504                    Binder.restoreCallingIdentity(origId);
17505                }
17506            }
17507        }
17508
17509        @Override
17510        public ActivityManager.RecentTaskInfo getTaskInfo() {
17511            // Ensure that we are called from the same process that created this AppTask
17512            if (mCallingUid != Binder.getCallingUid()) {
17513                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17514                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17515                return null;
17516            }
17517
17518            synchronized (ActivityManagerService.this) {
17519                long origId = Binder.clearCallingIdentity();
17520                try {
17521                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17522                    if (tr != null) {
17523                        return createRecentTaskInfoFromTaskRecord(tr);
17524                    }
17525                } finally {
17526                    Binder.restoreCallingIdentity(origId);
17527                }
17528                return null;
17529            }
17530        }
17531    }
17532}
17533