ActivityManagerService.java revision 41cd577c12a3525663101ff9217ded509bb869d6
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.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.net.Proxy;
142import android.net.ProxyInfo;
143import android.net.Uri;
144import android.os.Binder;
145import android.os.Build;
146import android.os.Bundle;
147import android.os.Debug;
148import android.os.DropBoxManager;
149import android.os.Environment;
150import android.os.FactoryTest;
151import android.os.FileObserver;
152import android.os.FileUtils;
153import android.os.Handler;
154import android.os.IBinder;
155import android.os.IPermissionController;
156import android.os.IRemoteCallback;
157import android.os.IUserManager;
158import android.os.Looper;
159import android.os.Message;
160import android.os.Parcel;
161import android.os.ParcelFileDescriptor;
162import android.os.Process;
163import android.os.RemoteCallbackList;
164import android.os.RemoteException;
165import android.os.SELinux;
166import android.os.ServiceManager;
167import android.os.StrictMode;
168import android.os.SystemClock;
169import android.os.SystemProperties;
170import android.os.UpdateLock;
171import android.os.UserHandle;
172import android.provider.Settings;
173import android.text.format.DateUtils;
174import android.text.format.Time;
175import android.util.AtomicFile;
176import android.util.EventLog;
177import android.util.Log;
178import android.util.Pair;
179import android.util.PrintWriterPrinter;
180import android.util.Slog;
181import android.util.SparseArray;
182import android.util.TimeUtils;
183import android.util.Xml;
184import android.view.Gravity;
185import android.view.LayoutInflater;
186import android.view.View;
187import android.view.WindowManager;
188
189import java.io.BufferedInputStream;
190import java.io.BufferedOutputStream;
191import java.io.DataInputStream;
192import java.io.DataOutputStream;
193import java.io.File;
194import java.io.FileDescriptor;
195import java.io.FileInputStream;
196import java.io.FileNotFoundException;
197import java.io.FileOutputStream;
198import java.io.IOException;
199import java.io.InputStreamReader;
200import java.io.PrintWriter;
201import java.io.StringWriter;
202import java.lang.ref.WeakReference;
203import java.util.ArrayList;
204import java.util.Arrays;
205import java.util.Collections;
206import java.util.Comparator;
207import java.util.HashMap;
208import java.util.HashSet;
209import java.util.Iterator;
210import java.util.List;
211import java.util.Locale;
212import java.util.Map;
213import java.util.Set;
214import java.util.concurrent.atomic.AtomicBoolean;
215import java.util.concurrent.atomic.AtomicLong;
216
217public final class ActivityManagerService extends ActivityManagerNative
218        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
219    private static final String USER_DATA_DIR = "/data/user/";
220    static final String TAG = "ActivityManager";
221    static final String TAG_MU = "ActivityManagerServiceMU";
222    static final boolean DEBUG = false;
223    static final boolean localLOGV = DEBUG;
224    static final boolean DEBUG_BACKUP = localLOGV || false;
225    static final boolean DEBUG_BROADCAST = localLOGV || false;
226    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
227    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_CLEANUP = localLOGV || false;
229    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
230    static final boolean DEBUG_FOCUS = false;
231    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
232    static final boolean DEBUG_MU = localLOGV || false;
233    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
234    static final boolean DEBUG_LRU = localLOGV || false;
235    static final boolean DEBUG_PAUSE = localLOGV || false;
236    static final boolean DEBUG_POWER = localLOGV || false;
237    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
238    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
239    static final boolean DEBUG_PROCESSES = localLOGV || false;
240    static final boolean DEBUG_PROVIDER = localLOGV || false;
241    static final boolean DEBUG_RESULTS = localLOGV || false;
242    static final boolean DEBUG_SERVICE = localLOGV || false;
243    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
244    static final boolean DEBUG_STACK = localLOGV || false;
245    static final boolean DEBUG_SWITCH = localLOGV || false;
246    static final boolean DEBUG_TASKS = localLOGV || false;
247    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
248    static final boolean DEBUG_TRANSITION = localLOGV || false;
249    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
250    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
251    static final boolean DEBUG_VISBILITY = localLOGV || false;
252    static final boolean DEBUG_PSS = localLOGV || false;
253    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
254    static final boolean VALIDATE_TOKENS = false;
255    static final boolean SHOW_ACTIVITY_START_TIME = true;
256
257    // Control over CPU and battery monitoring.
258    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
259    static final boolean MONITOR_CPU_USAGE = true;
260    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
261    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
262    static final boolean MONITOR_THREAD_CPU_USAGE = false;
263
264    // The flags that are set for all calls we make to the package manager.
265    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
266
267    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
268
269    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
270
271    // Maximum number of recent tasks that we can remember.
272    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
273
274    // Maximum number recent bitmaps to keep in memory.
275    static final int MAX_RECENT_BITMAPS = 5;
276
277    // Amount of time after a call to stopAppSwitches() during which we will
278    // prevent further untrusted switches from happening.
279    static final long APP_SWITCH_DELAY_TIME = 5*1000;
280
281    // How long we wait for a launched process to attach to the activity manager
282    // before we decide it's never going to come up for real.
283    static final int PROC_START_TIMEOUT = 10*1000;
284
285    // How long we wait for a launched process to attach to the activity manager
286    // before we decide it's never going to come up for real, when the process was
287    // started with a wrapper for instrumentation (such as Valgrind) because it
288    // could take much longer than usual.
289    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
290
291    // How long to wait after going idle before forcing apps to GC.
292    static final int GC_TIMEOUT = 5*1000;
293
294    // The minimum amount of time between successive GC requests for a process.
295    static final int GC_MIN_INTERVAL = 60*1000;
296
297    // The minimum amount of time between successive PSS requests for a process.
298    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
299
300    // The minimum amount of time between successive PSS requests for a process
301    // when the request is due to the memory state being lowered.
302    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
303
304    // The rate at which we check for apps using excessive power -- 15 mins.
305    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
306
307    // The minimum sample duration we will allow before deciding we have
308    // enough data on wake locks to start killing things.
309    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
310
311    // The minimum sample duration we will allow before deciding we have
312    // enough data on CPU usage to start killing things.
313    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
314
315    // How long we allow a receiver to run before giving up on it.
316    static final int BROADCAST_FG_TIMEOUT = 10*1000;
317    static final int BROADCAST_BG_TIMEOUT = 60*1000;
318
319    // How long we wait until we timeout on key dispatching.
320    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
321
322    // How long we wait until we timeout on key dispatching during instrumentation.
323    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
324
325    // Amount of time we wait for observers to handle a user switch before
326    // giving up on them and unfreezing the screen.
327    static final int USER_SWITCH_TIMEOUT = 2*1000;
328
329    // Maximum number of users we allow to be running at a time.
330    static final int MAX_RUNNING_USERS = 3;
331
332    // How long to wait in getAssistContextExtras for the activity and foreground services
333    // to respond with the result.
334    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
335
336    // Maximum number of persisted Uri grants a package is allowed
337    static final int MAX_PERSISTED_URI_GRANTS = 128;
338
339    static final int MY_PID = Process.myPid();
340
341    static final String[] EMPTY_STRING_ARRAY = new String[0];
342
343    // How many bytes to write into the dropbox log before truncating
344    static final int DROPBOX_MAX_SIZE = 256 * 1024;
345
346    /** All system services */
347    SystemServiceManager mSystemServiceManager;
348
349    /** Run all ActivityStacks through this */
350    ActivityStackSupervisor mStackSupervisor;
351
352    public IntentFirewall mIntentFirewall;
353
354    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
355    // default actuion automatically.  Important for devices without direct input
356    // devices.
357    private boolean mShowDialogs = true;
358
359    /**
360     * Description of a request to start a new activity, which has been held
361     * due to app switches being disabled.
362     */
363    static class PendingActivityLaunch {
364        final ActivityRecord r;
365        final ActivityRecord sourceRecord;
366        final int startFlags;
367        final ActivityStack stack;
368
369        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
370                int _startFlags, ActivityStack _stack) {
371            r = _r;
372            sourceRecord = _sourceRecord;
373            startFlags = _startFlags;
374            stack = _stack;
375        }
376    }
377
378    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
379            = new ArrayList<PendingActivityLaunch>();
380
381    BroadcastQueue mFgBroadcastQueue;
382    BroadcastQueue mBgBroadcastQueue;
383    // Convenient for easy iteration over the queues. Foreground is first
384    // so that dispatch of foreground broadcasts gets precedence.
385    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
386
387    BroadcastQueue broadcastQueueForIntent(Intent intent) {
388        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
389        if (DEBUG_BACKGROUND_BROADCAST) {
390            Slog.i(TAG, "Broadcast intent " + intent + " on "
391                    + (isFg ? "foreground" : "background")
392                    + " queue");
393        }
394        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
395    }
396
397    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
398        for (BroadcastQueue queue : mBroadcastQueues) {
399            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
400            if (r != null) {
401                return r;
402            }
403        }
404        return null;
405    }
406
407    /**
408     * Activity we have told the window manager to have key focus.
409     */
410    ActivityRecord mFocusedActivity = null;
411
412    /**
413     * List of intents that were used to start the most recent tasks.
414     */
415    ArrayList<TaskRecord> mRecentTasks;
416
417    public class PendingAssistExtras extends Binder implements Runnable {
418        public final ActivityRecord activity;
419        public boolean haveResult = false;
420        public Bundle result = null;
421        public PendingAssistExtras(ActivityRecord _activity) {
422            activity = _activity;
423        }
424        @Override
425        public void run() {
426            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
427            synchronized (this) {
428                haveResult = true;
429                notifyAll();
430            }
431        }
432    }
433
434    final ArrayList<PendingAssistExtras> mPendingAssistExtras
435            = new ArrayList<PendingAssistExtras>();
436
437    /**
438     * Process management.
439     */
440    final ProcessList mProcessList = new ProcessList();
441
442    /**
443     * All of the applications we currently have running organized by name.
444     * The keys are strings of the application package name (as
445     * returned by the package manager), and the keys are ApplicationRecord
446     * objects.
447     */
448    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
449
450    /**
451     * Tracking long-term execution of processes to look for abuse and other
452     * bad app behavior.
453     */
454    final ProcessStatsService mProcessStats;
455
456    /**
457     * The currently running isolated processes.
458     */
459    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
460
461    /**
462     * Counter for assigning isolated process uids, to avoid frequently reusing the
463     * same ones.
464     */
465    int mNextIsolatedProcessUid = 0;
466
467    /**
468     * The currently running heavy-weight process, if any.
469     */
470    ProcessRecord mHeavyWeightProcess = null;
471
472    /**
473     * The last time that various processes have crashed.
474     */
475    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
476
477    /**
478     * Information about a process that is currently marked as bad.
479     */
480    static final class BadProcessInfo {
481        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
482            this.time = time;
483            this.shortMsg = shortMsg;
484            this.longMsg = longMsg;
485            this.stack = stack;
486        }
487
488        final long time;
489        final String shortMsg;
490        final String longMsg;
491        final String stack;
492    }
493
494    /**
495     * Set of applications that we consider to be bad, and will reject
496     * incoming broadcasts from (which the user has no control over).
497     * Processes are added to this set when they have crashed twice within
498     * a minimum amount of time; they are removed from it when they are
499     * later restarted (hopefully due to some user action).  The value is the
500     * time it was added to the list.
501     */
502    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
503
504    /**
505     * All of the processes we currently have running organized by pid.
506     * The keys are the pid running the application.
507     *
508     * <p>NOTE: This object is protected by its own lock, NOT the global
509     * activity manager lock!
510     */
511    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
512
513    /**
514     * All of the processes that have been forced to be foreground.  The key
515     * is the pid of the caller who requested it (we hold a death
516     * link on it).
517     */
518    abstract class ForegroundToken implements IBinder.DeathRecipient {
519        int pid;
520        IBinder token;
521    }
522    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
523
524    /**
525     * List of records for processes that someone had tried to start before the
526     * system was ready.  We don't start them at that point, but ensure they
527     * are started by the time booting is complete.
528     */
529    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
530
531    /**
532     * List of persistent applications that are in the process
533     * of being started.
534     */
535    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
536
537    /**
538     * Processes that are being forcibly torn down.
539     */
540    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
541
542    /**
543     * List of running applications, sorted by recent usage.
544     * The first entry in the list is the least recently used.
545     */
546    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
547
548    /**
549     * Where in mLruProcesses that the processes hosting activities start.
550     */
551    int mLruProcessActivityStart = 0;
552
553    /**
554     * Where in mLruProcesses that the processes hosting services start.
555     * This is after (lower index) than mLruProcessesActivityStart.
556     */
557    int mLruProcessServiceStart = 0;
558
559    /**
560     * List of processes that should gc as soon as things are idle.
561     */
562    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes we want to collect PSS data from.
566     */
567    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * Last time we requested PSS data of all processes.
571     */
572    long mLastFullPssTime = SystemClock.uptimeMillis();
573
574    /**
575     * If set, the next time we collect PSS data we should do a full collection
576     * with data from native processes and the kernel.
577     */
578    boolean mFullPssPending = false;
579
580    /**
581     * This is the process holding what we currently consider to be
582     * the "home" activity.
583     */
584    ProcessRecord mHomeProcess;
585
586    /**
587     * This is the process holding the activity the user last visited that
588     * is in a different process from the one they are currently in.
589     */
590    ProcessRecord mPreviousProcess;
591
592    /**
593     * The time at which the previous process was last visible.
594     */
595    long mPreviousProcessVisibleTime;
596
597    /**
598     * Which uses have been started, so are allowed to run code.
599     */
600    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
601
602    /**
603     * LRU list of history of current users.  Most recently current is at the end.
604     */
605    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
606
607    /**
608     * Constant array of the users that are currently started.
609     */
610    int[] mStartedUserArray = new int[] { 0 };
611
612    /**
613     * Registered observers of the user switching mechanics.
614     */
615    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
616            = new RemoteCallbackList<IUserSwitchObserver>();
617
618    /**
619     * Currently active user switch.
620     */
621    Object mCurUserSwitchCallback;
622
623    /**
624     * Packages that the user has asked to have run in screen size
625     * compatibility mode instead of filling the screen.
626     */
627    final CompatModePackages mCompatModePackages;
628
629    /**
630     * Set of IntentSenderRecord objects that are currently active.
631     */
632    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
633            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
634
635    /**
636     * Fingerprints (hashCode()) of stack traces that we've
637     * already logged DropBox entries for.  Guarded by itself.  If
638     * something (rogue user app) forces this over
639     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
640     */
641    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
642    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
643
644    /**
645     * Strict Mode background batched logging state.
646     *
647     * The string buffer is guarded by itself, and its lock is also
648     * used to determine if another batched write is already
649     * in-flight.
650     */
651    private final StringBuilder mStrictModeBuffer = new StringBuilder();
652
653    /**
654     * Keeps track of all IIntentReceivers that have been registered for
655     * broadcasts.  Hash keys are the receiver IBinder, hash value is
656     * a ReceiverList.
657     */
658    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
659            new HashMap<IBinder, ReceiverList>();
660
661    /**
662     * Resolver for broadcast intents to registered receivers.
663     * Holds BroadcastFilter (subclass of IntentFilter).
664     */
665    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
666            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
667        @Override
668        protected boolean allowFilterResult(
669                BroadcastFilter filter, List<BroadcastFilter> dest) {
670            IBinder target = filter.receiverList.receiver.asBinder();
671            for (int i=dest.size()-1; i>=0; i--) {
672                if (dest.get(i).receiverList.receiver.asBinder() == target) {
673                    return false;
674                }
675            }
676            return true;
677        }
678
679        @Override
680        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
681            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
682                    || userId == filter.owningUserId) {
683                return super.newResult(filter, match, userId);
684            }
685            return null;
686        }
687
688        @Override
689        protected BroadcastFilter[] newArray(int size) {
690            return new BroadcastFilter[size];
691        }
692
693        @Override
694        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
695            return packageName.equals(filter.packageName);
696        }
697    };
698
699    /**
700     * State of all active sticky broadcasts per user.  Keys are the action of the
701     * sticky Intent, values are an ArrayList of all broadcasted intents with
702     * that action (which should usually be one).  The SparseArray is keyed
703     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
704     * for stickies that are sent to all users.
705     */
706    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
707            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
708
709    final ActiveServices mServices;
710
711    /**
712     * Backup/restore process management
713     */
714    String mBackupAppName = null;
715    BackupRecord mBackupTarget = null;
716
717    final ProviderMap mProviderMap;
718
719    /**
720     * List of content providers who have clients waiting for them.  The
721     * application is currently being launched and the provider will be
722     * removed from this list once it is published.
723     */
724    final ArrayList<ContentProviderRecord> mLaunchingProviders
725            = new ArrayList<ContentProviderRecord>();
726
727    /**
728     * File storing persisted {@link #mGrantedUriPermissions}.
729     */
730    private final AtomicFile mGrantFile;
731
732    /** XML constants used in {@link #mGrantFile} */
733    private static final String TAG_URI_GRANTS = "uri-grants";
734    private static final String TAG_URI_GRANT = "uri-grant";
735    private static final String ATTR_USER_HANDLE = "userHandle";
736    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
737    private static final String ATTR_TARGET_USER_ID = "targetUserId";
738    private static final String ATTR_SOURCE_PKG = "sourcePkg";
739    private static final String ATTR_TARGET_PKG = "targetPkg";
740    private static final String ATTR_URI = "uri";
741    private static final String ATTR_MODE_FLAGS = "modeFlags";
742    private static final String ATTR_CREATED_TIME = "createdTime";
743    private static final String ATTR_PREFIX = "prefix";
744
745    /**
746     * Global set of specific {@link Uri} permissions that have been granted.
747     * This optimized lookup structure maps from {@link UriPermission#targetUid}
748     * to {@link UriPermission#uri} to {@link UriPermission}.
749     */
750    @GuardedBy("this")
751    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
752            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
753
754    public static class GrantUri {
755        public final int sourceUserId;
756        public final Uri uri;
757        public boolean prefix;
758
759        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
760            this.sourceUserId = sourceUserId;
761            this.uri = uri;
762            this.prefix = prefix;
763        }
764
765        @Override
766        public int hashCode() {
767            return toString().hashCode();
768        }
769
770        @Override
771        public boolean equals(Object o) {
772            if (o instanceof GrantUri) {
773                GrantUri other = (GrantUri) o;
774                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
775                        && prefix == other.prefix;
776            }
777            return false;
778        }
779
780        @Override
781        public String toString() {
782            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
783            if (prefix) result += " [prefix]";
784            return result;
785        }
786
787        public String toSafeString() {
788            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
789            if (prefix) result += " [prefix]";
790            return result;
791        }
792
793        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
794            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
795                    ContentProvider.getUriWithoutUserId(uri), false);
796        }
797    }
798
799    CoreSettingsObserver mCoreSettingsObserver;
800
801    /**
802     * Thread-local storage used to carry caller permissions over through
803     * indirect content-provider access.
804     */
805    private class Identity {
806        public int pid;
807        public int uid;
808
809        Identity(int _pid, int _uid) {
810            pid = _pid;
811            uid = _uid;
812        }
813    }
814
815    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
816
817    /**
818     * All information we have collected about the runtime performance of
819     * any user id that can impact battery performance.
820     */
821    final BatteryStatsService mBatteryStatsService;
822
823    /**
824     * Information about component usage
825     */
826    final UsageStatsService mUsageStatsService;
827
828    /**
829     * Information about and control over application operations
830     */
831    final AppOpsService mAppOpsService;
832
833    /**
834     * Save recent tasks information across reboots.
835     */
836    final TaskPersister mTaskPersister;
837
838    /**
839     * Current configuration information.  HistoryRecord objects are given
840     * a reference to this object to indicate which configuration they are
841     * currently running in, so this object must be kept immutable.
842     */
843    Configuration mConfiguration = new Configuration();
844
845    /**
846     * Current sequencing integer of the configuration, for skipping old
847     * configurations.
848     */
849    int mConfigurationSeq = 0;
850
851    /**
852     * Hardware-reported OpenGLES version.
853     */
854    final int GL_ES_VERSION;
855
856    /**
857     * List of initialization arguments to pass to all processes when binding applications to them.
858     * For example, references to the commonly used services.
859     */
860    HashMap<String, IBinder> mAppBindArgs;
861
862    /**
863     * Temporary to avoid allocations.  Protected by main lock.
864     */
865    final StringBuilder mStringBuilder = new StringBuilder(256);
866
867    /**
868     * Used to control how we initialize the service.
869     */
870    ComponentName mTopComponent;
871    String mTopAction = Intent.ACTION_MAIN;
872    String mTopData;
873    boolean mProcessesReady = false;
874    boolean mSystemReady = false;
875    boolean mBooting = false;
876    boolean mWaitingUpdate = false;
877    boolean mDidUpdate = false;
878    boolean mOnBattery = false;
879    boolean mLaunchWarningShown = false;
880
881    Context mContext;
882
883    int mFactoryTest;
884
885    boolean mCheckedForSetup;
886
887    /**
888     * The time at which we will allow normal application switches again,
889     * after a call to {@link #stopAppSwitches()}.
890     */
891    long mAppSwitchesAllowedTime;
892
893    /**
894     * This is set to true after the first switch after mAppSwitchesAllowedTime
895     * is set; any switches after that will clear the time.
896     */
897    boolean mDidAppSwitch;
898
899    /**
900     * Last time (in realtime) at which we checked for power usage.
901     */
902    long mLastPowerCheckRealtime;
903
904    /**
905     * Last time (in uptime) at which we checked for power usage.
906     */
907    long mLastPowerCheckUptime;
908
909    /**
910     * Set while we are wanting to sleep, to prevent any
911     * activities from being started/resumed.
912     */
913    private boolean mSleeping = false;
914
915    /**
916     * Set while we are running a voice interaction.  This overrides
917     * sleeping while it is active.
918     */
919    private boolean mRunningVoice = false;
920
921    /**
922     * State of external calls telling us if the device is asleep.
923     */
924    private boolean mWentToSleep = false;
925
926    /**
927     * State of external call telling us if the lock screen is shown.
928     */
929    private boolean mLockScreenShown = false;
930
931    /**
932     * Set if we are shutting down the system, similar to sleeping.
933     */
934    boolean mShuttingDown = false;
935
936    /**
937     * Current sequence id for oom_adj computation traversal.
938     */
939    int mAdjSeq = 0;
940
941    /**
942     * Current sequence id for process LRU updating.
943     */
944    int mLruSeq = 0;
945
946    /**
947     * Keep track of the non-cached/empty process we last found, to help
948     * determine how to distribute cached/empty processes next time.
949     */
950    int mNumNonCachedProcs = 0;
951
952    /**
953     * Keep track of the number of cached hidden procs, to balance oom adj
954     * distribution between those and empty procs.
955     */
956    int mNumCachedHiddenProcs = 0;
957
958    /**
959     * Keep track of the number of service processes we last found, to
960     * determine on the next iteration which should be B services.
961     */
962    int mNumServiceProcs = 0;
963    int mNewNumAServiceProcs = 0;
964    int mNewNumServiceProcs = 0;
965
966    /**
967     * Allow the current computed overall memory level of the system to go down?
968     * This is set to false when we are killing processes for reasons other than
969     * memory management, so that the now smaller process list will not be taken as
970     * an indication that memory is tighter.
971     */
972    boolean mAllowLowerMemLevel = false;
973
974    /**
975     * The last computed memory level, for holding when we are in a state that
976     * processes are going away for other reasons.
977     */
978    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
979
980    /**
981     * The last total number of process we have, to determine if changes actually look
982     * like a shrinking number of process due to lower RAM.
983     */
984    int mLastNumProcesses;
985
986    /**
987     * The uptime of the last time we performed idle maintenance.
988     */
989    long mLastIdleTime = SystemClock.uptimeMillis();
990
991    /**
992     * Total time spent with RAM that has been added in the past since the last idle time.
993     */
994    long mLowRamTimeSinceLastIdle = 0;
995
996    /**
997     * If RAM is currently low, when that horrible situation started.
998     */
999    long mLowRamStartTime = 0;
1000
1001    /**
1002     * For reporting to battery stats the current top application.
1003     */
1004    private String mCurResumedPackage = null;
1005    private int mCurResumedUid = -1;
1006
1007    /**
1008     * For reporting to battery stats the apps currently running foreground
1009     * service.  The ProcessMap is package/uid tuples; each of these contain
1010     * an array of the currently foreground processes.
1011     */
1012    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1013            = new ProcessMap<ArrayList<ProcessRecord>>();
1014
1015    /**
1016     * This is set if we had to do a delayed dexopt of an app before launching
1017     * it, to increase the ANR timeouts in that case.
1018     */
1019    boolean mDidDexOpt;
1020
1021    /**
1022     * Set if the systemServer made a call to enterSafeMode.
1023     */
1024    boolean mSafeMode;
1025
1026    String mDebugApp = null;
1027    boolean mWaitForDebugger = false;
1028    boolean mDebugTransient = false;
1029    String mOrigDebugApp = null;
1030    boolean mOrigWaitForDebugger = false;
1031    boolean mAlwaysFinishActivities = false;
1032    IActivityController mController = null;
1033    String mProfileApp = null;
1034    ProcessRecord mProfileProc = null;
1035    String mProfileFile;
1036    ParcelFileDescriptor mProfileFd;
1037    int mProfileType = 0;
1038    boolean mAutoStopProfiler = false;
1039    String mOpenGlTraceApp = null;
1040
1041    static class ProcessChangeItem {
1042        static final int CHANGE_ACTIVITIES = 1<<0;
1043        static final int CHANGE_PROCESS_STATE = 1<<1;
1044        int changes;
1045        int uid;
1046        int pid;
1047        int processState;
1048        boolean foregroundActivities;
1049    }
1050
1051    final RemoteCallbackList<IProcessObserver> mProcessObservers
1052            = new RemoteCallbackList<IProcessObserver>();
1053    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1054
1055    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1056            = new ArrayList<ProcessChangeItem>();
1057    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1058            = new ArrayList<ProcessChangeItem>();
1059
1060    /**
1061     * Runtime CPU use collection thread.  This object's lock is used to
1062     * protect all related state.
1063     */
1064    final Thread mProcessCpuThread;
1065
1066    /**
1067     * Used to collect process stats when showing not responding dialog.
1068     * Protected by mProcessCpuThread.
1069     */
1070    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1071            MONITOR_THREAD_CPU_USAGE);
1072    final AtomicLong mLastCpuTime = new AtomicLong(0);
1073    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1074
1075    long mLastWriteTime = 0;
1076
1077    /**
1078     * Used to retain an update lock when the foreground activity is in
1079     * immersive mode.
1080     */
1081    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1082
1083    /**
1084     * Set to true after the system has finished booting.
1085     */
1086    boolean mBooted = false;
1087
1088    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1089    int mProcessLimitOverride = -1;
1090
1091    WindowManagerService mWindowManager;
1092
1093    final ActivityThread mSystemThread;
1094
1095    int mCurrentUserId = 0;
1096    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1097    private UserManagerService mUserManager;
1098
1099    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1100        final ProcessRecord mApp;
1101        final int mPid;
1102        final IApplicationThread mAppThread;
1103
1104        AppDeathRecipient(ProcessRecord app, int pid,
1105                IApplicationThread thread) {
1106            if (localLOGV) Slog.v(
1107                TAG, "New death recipient " + this
1108                + " for thread " + thread.asBinder());
1109            mApp = app;
1110            mPid = pid;
1111            mAppThread = thread;
1112        }
1113
1114        @Override
1115        public void binderDied() {
1116            if (localLOGV) Slog.v(
1117                TAG, "Death received in " + this
1118                + " for thread " + mAppThread.asBinder());
1119            synchronized(ActivityManagerService.this) {
1120                appDiedLocked(mApp, mPid, mAppThread);
1121            }
1122        }
1123    }
1124
1125    static final int SHOW_ERROR_MSG = 1;
1126    static final int SHOW_NOT_RESPONDING_MSG = 2;
1127    static final int SHOW_FACTORY_ERROR_MSG = 3;
1128    static final int UPDATE_CONFIGURATION_MSG = 4;
1129    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1130    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1131    static final int SERVICE_TIMEOUT_MSG = 12;
1132    static final int UPDATE_TIME_ZONE = 13;
1133    static final int SHOW_UID_ERROR_MSG = 14;
1134    static final int IM_FEELING_LUCKY_MSG = 15;
1135    static final int PROC_START_TIMEOUT_MSG = 20;
1136    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1137    static final int KILL_APPLICATION_MSG = 22;
1138    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1139    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1140    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1141    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1142    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1143    static final int CLEAR_DNS_CACHE_MSG = 28;
1144    static final int UPDATE_HTTP_PROXY_MSG = 29;
1145    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1146    static final int DISPATCH_PROCESSES_CHANGED = 31;
1147    static final int DISPATCH_PROCESS_DIED = 32;
1148    static final int REPORT_MEM_USAGE_MSG = 33;
1149    static final int REPORT_USER_SWITCH_MSG = 34;
1150    static final int CONTINUE_USER_SWITCH_MSG = 35;
1151    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1152    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1153    static final int PERSIST_URI_GRANTS_MSG = 38;
1154    static final int REQUEST_ALL_PSS_MSG = 39;
1155    static final int START_PROFILES_MSG = 40;
1156    static final int UPDATE_TIME = 41;
1157    static final int SYSTEM_USER_START_MSG = 42;
1158    static final int SYSTEM_USER_CURRENT_MSG = 43;
1159
1160    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1161    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1162    static final int FIRST_COMPAT_MODE_MSG = 300;
1163    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1164
1165    AlertDialog mUidAlert;
1166    CompatModeDialog mCompatModeDialog;
1167    long mLastMemUsageReportTime = 0;
1168
1169    private LockToAppRequestDialog mLockToAppRequest;
1170
1171    /**
1172     * Flag whether the current user is a "monkey", i.e. whether
1173     * the UI is driven by a UI automation tool.
1174     */
1175    private boolean mUserIsMonkey;
1176
1177    final ServiceThread mHandlerThread;
1178    final MainHandler mHandler;
1179
1180    final class MainHandler extends Handler {
1181        public MainHandler(Looper looper) {
1182            super(looper, null, true);
1183        }
1184
1185        @Override
1186        public void handleMessage(Message msg) {
1187            switch (msg.what) {
1188            case SHOW_ERROR_MSG: {
1189                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1190                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1191                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1192                synchronized (ActivityManagerService.this) {
1193                    ProcessRecord proc = (ProcessRecord)data.get("app");
1194                    AppErrorResult res = (AppErrorResult) data.get("result");
1195                    if (proc != null && proc.crashDialog != null) {
1196                        Slog.e(TAG, "App already has crash dialog: " + proc);
1197                        if (res != null) {
1198                            res.set(0);
1199                        }
1200                        return;
1201                    }
1202                    if (!showBackground && UserHandle.getAppId(proc.uid)
1203                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1204                            && proc.pid != MY_PID) {
1205                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1206                        if (res != null) {
1207                            res.set(0);
1208                        }
1209                        return;
1210                    }
1211                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1212                        Dialog d = new AppErrorDialog(mContext,
1213                                ActivityManagerService.this, res, proc);
1214                        d.show();
1215                        proc.crashDialog = d;
1216                    } else {
1217                        // The device is asleep, so just pretend that the user
1218                        // saw a crash dialog and hit "force quit".
1219                        if (res != null) {
1220                            res.set(0);
1221                        }
1222                    }
1223                }
1224
1225                ensureBootCompleted();
1226            } break;
1227            case SHOW_NOT_RESPONDING_MSG: {
1228                synchronized (ActivityManagerService.this) {
1229                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1230                    ProcessRecord proc = (ProcessRecord)data.get("app");
1231                    if (proc != null && proc.anrDialog != null) {
1232                        Slog.e(TAG, "App already has anr dialog: " + proc);
1233                        return;
1234                    }
1235
1236                    Intent intent = new Intent("android.intent.action.ANR");
1237                    if (!mProcessesReady) {
1238                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1239                                | Intent.FLAG_RECEIVER_FOREGROUND);
1240                    }
1241                    broadcastIntentLocked(null, null, intent,
1242                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1243                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1244
1245                    if (mShowDialogs) {
1246                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1247                                mContext, proc, (ActivityRecord)data.get("activity"),
1248                                msg.arg1 != 0);
1249                        d.show();
1250                        proc.anrDialog = d;
1251                    } else {
1252                        // Just kill the app if there is no dialog to be shown.
1253                        killAppAtUsersRequest(proc, null);
1254                    }
1255                }
1256
1257                ensureBootCompleted();
1258            } break;
1259            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1260                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1261                synchronized (ActivityManagerService.this) {
1262                    ProcessRecord proc = (ProcessRecord) data.get("app");
1263                    if (proc == null) {
1264                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1265                        break;
1266                    }
1267                    if (proc.crashDialog != null) {
1268                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1269                        return;
1270                    }
1271                    AppErrorResult res = (AppErrorResult) data.get("result");
1272                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1273                        Dialog d = new StrictModeViolationDialog(mContext,
1274                                ActivityManagerService.this, res, proc);
1275                        d.show();
1276                        proc.crashDialog = d;
1277                    } else {
1278                        // The device is asleep, so just pretend that the user
1279                        // saw a crash dialog and hit "force quit".
1280                        res.set(0);
1281                    }
1282                }
1283                ensureBootCompleted();
1284            } break;
1285            case SHOW_FACTORY_ERROR_MSG: {
1286                Dialog d = new FactoryErrorDialog(
1287                    mContext, msg.getData().getCharSequence("msg"));
1288                d.show();
1289                ensureBootCompleted();
1290            } break;
1291            case UPDATE_CONFIGURATION_MSG: {
1292                final ContentResolver resolver = mContext.getContentResolver();
1293                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1294            } break;
1295            case GC_BACKGROUND_PROCESSES_MSG: {
1296                synchronized (ActivityManagerService.this) {
1297                    performAppGcsIfAppropriateLocked();
1298                }
1299            } break;
1300            case WAIT_FOR_DEBUGGER_MSG: {
1301                synchronized (ActivityManagerService.this) {
1302                    ProcessRecord app = (ProcessRecord)msg.obj;
1303                    if (msg.arg1 != 0) {
1304                        if (!app.waitedForDebugger) {
1305                            Dialog d = new AppWaitingForDebuggerDialog(
1306                                    ActivityManagerService.this,
1307                                    mContext, app);
1308                            app.waitDialog = d;
1309                            app.waitedForDebugger = true;
1310                            d.show();
1311                        }
1312                    } else {
1313                        if (app.waitDialog != null) {
1314                            app.waitDialog.dismiss();
1315                            app.waitDialog = null;
1316                        }
1317                    }
1318                }
1319            } break;
1320            case SERVICE_TIMEOUT_MSG: {
1321                if (mDidDexOpt) {
1322                    mDidDexOpt = false;
1323                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1324                    nmsg.obj = msg.obj;
1325                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1326                    return;
1327                }
1328                mServices.serviceTimeout((ProcessRecord)msg.obj);
1329            } break;
1330            case UPDATE_TIME_ZONE: {
1331                synchronized (ActivityManagerService.this) {
1332                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1333                        ProcessRecord r = mLruProcesses.get(i);
1334                        if (r.thread != null) {
1335                            try {
1336                                r.thread.updateTimeZone();
1337                            } catch (RemoteException ex) {
1338                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1339                            }
1340                        }
1341                    }
1342                }
1343            } break;
1344            case CLEAR_DNS_CACHE_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1347                        ProcessRecord r = mLruProcesses.get(i);
1348                        if (r.thread != null) {
1349                            try {
1350                                r.thread.clearDnsCache();
1351                            } catch (RemoteException ex) {
1352                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1353                            }
1354                        }
1355                    }
1356                }
1357            } break;
1358            case UPDATE_HTTP_PROXY_MSG: {
1359                ProxyInfo proxy = (ProxyInfo)msg.obj;
1360                String host = "";
1361                String port = "";
1362                String exclList = "";
1363                Uri pacFileUrl = Uri.EMPTY;
1364                if (proxy != null) {
1365                    host = proxy.getHost();
1366                    port = Integer.toString(proxy.getPort());
1367                    exclList = proxy.getExclusionListAsString();
1368                    pacFileUrl = proxy.getPacFileUrl();
1369                }
1370                synchronized (ActivityManagerService.this) {
1371                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1372                        ProcessRecord r = mLruProcesses.get(i);
1373                        if (r.thread != null) {
1374                            try {
1375                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1376                            } catch (RemoteException ex) {
1377                                Slog.w(TAG, "Failed to update http proxy for: " +
1378                                        r.info.processName);
1379                            }
1380                        }
1381                    }
1382                }
1383            } break;
1384            case SHOW_UID_ERROR_MSG: {
1385                String title = "System UIDs Inconsistent";
1386                String text = "UIDs on the system are inconsistent, you need to wipe your"
1387                        + " data partition or your device will be unstable.";
1388                Log.e(TAG, title + ": " + text);
1389                if (mShowDialogs) {
1390                    // XXX This is a temporary dialog, no need to localize.
1391                    AlertDialog d = new BaseErrorDialog(mContext);
1392                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1393                    d.setCancelable(false);
1394                    d.setTitle(title);
1395                    d.setMessage(text);
1396                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1397                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1398                    mUidAlert = d;
1399                    d.show();
1400                }
1401            } break;
1402            case IM_FEELING_LUCKY_MSG: {
1403                if (mUidAlert != null) {
1404                    mUidAlert.dismiss();
1405                    mUidAlert = null;
1406                }
1407            } break;
1408            case PROC_START_TIMEOUT_MSG: {
1409                if (mDidDexOpt) {
1410                    mDidDexOpt = false;
1411                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1412                    nmsg.obj = msg.obj;
1413                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1414                    return;
1415                }
1416                ProcessRecord app = (ProcessRecord)msg.obj;
1417                synchronized (ActivityManagerService.this) {
1418                    processStartTimedOutLocked(app);
1419                }
1420            } break;
1421            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1422                synchronized (ActivityManagerService.this) {
1423                    doPendingActivityLaunchesLocked(true);
1424                }
1425            } break;
1426            case KILL_APPLICATION_MSG: {
1427                synchronized (ActivityManagerService.this) {
1428                    int appid = msg.arg1;
1429                    boolean restart = (msg.arg2 == 1);
1430                    Bundle bundle = (Bundle)msg.obj;
1431                    String pkg = bundle.getString("pkg");
1432                    String reason = bundle.getString("reason");
1433                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1434                            false, UserHandle.USER_ALL, reason);
1435                }
1436            } break;
1437            case FINALIZE_PENDING_INTENT_MSG: {
1438                ((PendingIntentRecord)msg.obj).completeFinalize();
1439            } break;
1440            case POST_HEAVY_NOTIFICATION_MSG: {
1441                INotificationManager inm = NotificationManager.getService();
1442                if (inm == null) {
1443                    return;
1444                }
1445
1446                ActivityRecord root = (ActivityRecord)msg.obj;
1447                ProcessRecord process = root.app;
1448                if (process == null) {
1449                    return;
1450                }
1451
1452                try {
1453                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1454                    String text = mContext.getString(R.string.heavy_weight_notification,
1455                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1456                    Notification notification = new Notification();
1457                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1458                    notification.when = 0;
1459                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1460                    notification.tickerText = text;
1461                    notification.defaults = 0; // please be quiet
1462                    notification.sound = null;
1463                    notification.vibrate = null;
1464                    notification.setLatestEventInfo(context, text,
1465                            mContext.getText(R.string.heavy_weight_notification_detail),
1466                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1467                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1468                                    new UserHandle(root.userId)));
1469
1470                    try {
1471                        int[] outId = new int[1];
1472                        inm.enqueueNotificationWithTag("android", "android", null,
1473                                R.string.heavy_weight_notification,
1474                                notification, outId, root.userId);
1475                    } catch (RuntimeException e) {
1476                        Slog.w(ActivityManagerService.TAG,
1477                                "Error showing notification for heavy-weight app", e);
1478                    } catch (RemoteException e) {
1479                    }
1480                } catch (NameNotFoundException e) {
1481                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1482                }
1483            } break;
1484            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1485                INotificationManager inm = NotificationManager.getService();
1486                if (inm == null) {
1487                    return;
1488                }
1489                try {
1490                    inm.cancelNotificationWithTag("android", null,
1491                            R.string.heavy_weight_notification,  msg.arg1);
1492                } catch (RuntimeException e) {
1493                    Slog.w(ActivityManagerService.TAG,
1494                            "Error canceling notification for service", e);
1495                } catch (RemoteException e) {
1496                }
1497            } break;
1498            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1499                synchronized (ActivityManagerService.this) {
1500                    checkExcessivePowerUsageLocked(true);
1501                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1502                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1503                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1504                }
1505            } break;
1506            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1507                synchronized (ActivityManagerService.this) {
1508                    ActivityRecord ar = (ActivityRecord)msg.obj;
1509                    if (mCompatModeDialog != null) {
1510                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1511                                ar.info.applicationInfo.packageName)) {
1512                            return;
1513                        }
1514                        mCompatModeDialog.dismiss();
1515                        mCompatModeDialog = null;
1516                    }
1517                    if (ar != null && false) {
1518                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1519                                ar.packageName)) {
1520                            int mode = mCompatModePackages.computeCompatModeLocked(
1521                                    ar.info.applicationInfo);
1522                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1523                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1524                                mCompatModeDialog = new CompatModeDialog(
1525                                        ActivityManagerService.this, mContext,
1526                                        ar.info.applicationInfo);
1527                                mCompatModeDialog.show();
1528                            }
1529                        }
1530                    }
1531                }
1532                break;
1533            }
1534            case DISPATCH_PROCESSES_CHANGED: {
1535                dispatchProcessesChanged();
1536                break;
1537            }
1538            case DISPATCH_PROCESS_DIED: {
1539                final int pid = msg.arg1;
1540                final int uid = msg.arg2;
1541                dispatchProcessDied(pid, uid);
1542                break;
1543            }
1544            case REPORT_MEM_USAGE_MSG: {
1545                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1546                Thread thread = new Thread() {
1547                    @Override public void run() {
1548                        final SparseArray<ProcessMemInfo> infoMap
1549                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1550                        for (int i=0, N=memInfos.size(); i<N; i++) {
1551                            ProcessMemInfo mi = memInfos.get(i);
1552                            infoMap.put(mi.pid, mi);
1553                        }
1554                        updateCpuStatsNow();
1555                        synchronized (mProcessCpuThread) {
1556                            final int N = mProcessCpuTracker.countStats();
1557                            for (int i=0; i<N; i++) {
1558                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1559                                if (st.vsize > 0) {
1560                                    long pss = Debug.getPss(st.pid, null);
1561                                    if (pss > 0) {
1562                                        if (infoMap.indexOfKey(st.pid) < 0) {
1563                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1564                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1565                                            mi.pss = pss;
1566                                            memInfos.add(mi);
1567                                        }
1568                                    }
1569                                }
1570                            }
1571                        }
1572
1573                        long totalPss = 0;
1574                        for (int i=0, N=memInfos.size(); i<N; i++) {
1575                            ProcessMemInfo mi = memInfos.get(i);
1576                            if (mi.pss == 0) {
1577                                mi.pss = Debug.getPss(mi.pid, null);
1578                            }
1579                            totalPss += mi.pss;
1580                        }
1581                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1582                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1583                                if (lhs.oomAdj != rhs.oomAdj) {
1584                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1585                                }
1586                                if (lhs.pss != rhs.pss) {
1587                                    return lhs.pss < rhs.pss ? 1 : -1;
1588                                }
1589                                return 0;
1590                            }
1591                        });
1592
1593                        StringBuilder tag = new StringBuilder(128);
1594                        StringBuilder stack = new StringBuilder(128);
1595                        tag.append("Low on memory -- ");
1596                        appendMemBucket(tag, totalPss, "total", false);
1597                        appendMemBucket(stack, totalPss, "total", true);
1598
1599                        StringBuilder logBuilder = new StringBuilder(1024);
1600                        logBuilder.append("Low on memory:\n");
1601
1602                        boolean firstLine = true;
1603                        int lastOomAdj = Integer.MIN_VALUE;
1604                        for (int i=0, N=memInfos.size(); i<N; i++) {
1605                            ProcessMemInfo mi = memInfos.get(i);
1606
1607                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1608                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1609                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1610                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1611                                if (lastOomAdj != mi.oomAdj) {
1612                                    lastOomAdj = mi.oomAdj;
1613                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1614                                        tag.append(" / ");
1615                                    }
1616                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1617                                        if (firstLine) {
1618                                            stack.append(":");
1619                                            firstLine = false;
1620                                        }
1621                                        stack.append("\n\t at ");
1622                                    } else {
1623                                        stack.append("$");
1624                                    }
1625                                } else {
1626                                    tag.append(" ");
1627                                    stack.append("$");
1628                                }
1629                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1630                                    appendMemBucket(tag, mi.pss, mi.name, false);
1631                                }
1632                                appendMemBucket(stack, mi.pss, mi.name, true);
1633                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1634                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1635                                    stack.append("(");
1636                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1637                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1638                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1639                                            stack.append(":");
1640                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1641                                        }
1642                                    }
1643                                    stack.append(")");
1644                                }
1645                            }
1646
1647                            logBuilder.append("  ");
1648                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1649                            logBuilder.append(' ');
1650                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1651                            logBuilder.append(' ');
1652                            ProcessList.appendRamKb(logBuilder, mi.pss);
1653                            logBuilder.append(" kB: ");
1654                            logBuilder.append(mi.name);
1655                            logBuilder.append(" (");
1656                            logBuilder.append(mi.pid);
1657                            logBuilder.append(") ");
1658                            logBuilder.append(mi.adjType);
1659                            logBuilder.append('\n');
1660                            if (mi.adjReason != null) {
1661                                logBuilder.append("                      ");
1662                                logBuilder.append(mi.adjReason);
1663                                logBuilder.append('\n');
1664                            }
1665                        }
1666
1667                        logBuilder.append("           ");
1668                        ProcessList.appendRamKb(logBuilder, totalPss);
1669                        logBuilder.append(" kB: TOTAL\n");
1670
1671                        long[] infos = new long[Debug.MEMINFO_COUNT];
1672                        Debug.getMemInfo(infos);
1673                        logBuilder.append("  MemInfo: ");
1674                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1675                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1676                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1677                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1678                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1679                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1680                            logBuilder.append("  ZRAM: ");
1681                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1682                            logBuilder.append(" kB RAM, ");
1683                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1684                            logBuilder.append(" kB swap total, ");
1685                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1686                            logBuilder.append(" kB swap free\n");
1687                        }
1688                        Slog.i(TAG, logBuilder.toString());
1689
1690                        StringBuilder dropBuilder = new StringBuilder(1024);
1691                        /*
1692                        StringWriter oomSw = new StringWriter();
1693                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1694                        StringWriter catSw = new StringWriter();
1695                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1696                        String[] emptyArgs = new String[] { };
1697                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1698                        oomPw.flush();
1699                        String oomString = oomSw.toString();
1700                        */
1701                        dropBuilder.append(stack);
1702                        dropBuilder.append('\n');
1703                        dropBuilder.append('\n');
1704                        dropBuilder.append(logBuilder);
1705                        dropBuilder.append('\n');
1706                        /*
1707                        dropBuilder.append(oomString);
1708                        dropBuilder.append('\n');
1709                        */
1710                        StringWriter catSw = new StringWriter();
1711                        synchronized (ActivityManagerService.this) {
1712                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1713                            String[] emptyArgs = new String[] { };
1714                            catPw.println();
1715                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1716                            catPw.println();
1717                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1718                                    false, false, null);
1719                            catPw.println();
1720                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1721                            catPw.flush();
1722                        }
1723                        dropBuilder.append(catSw.toString());
1724                        addErrorToDropBox("lowmem", null, "system_server", null,
1725                                null, tag.toString(), dropBuilder.toString(), null, null);
1726                        //Slog.i(TAG, "Sent to dropbox:");
1727                        //Slog.i(TAG, dropBuilder.toString());
1728                        synchronized (ActivityManagerService.this) {
1729                            long now = SystemClock.uptimeMillis();
1730                            if (mLastMemUsageReportTime < now) {
1731                                mLastMemUsageReportTime = now;
1732                            }
1733                        }
1734                    }
1735                };
1736                thread.start();
1737                break;
1738            }
1739            case REPORT_USER_SWITCH_MSG: {
1740                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1741                break;
1742            }
1743            case CONTINUE_USER_SWITCH_MSG: {
1744                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1745                break;
1746            }
1747            case USER_SWITCH_TIMEOUT_MSG: {
1748                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1749                break;
1750            }
1751            case IMMERSIVE_MODE_LOCK_MSG: {
1752                final boolean nextState = (msg.arg1 != 0);
1753                if (mUpdateLock.isHeld() != nextState) {
1754                    if (DEBUG_IMMERSIVE) {
1755                        final ActivityRecord r = (ActivityRecord) msg.obj;
1756                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1757                    }
1758                    if (nextState) {
1759                        mUpdateLock.acquire();
1760                    } else {
1761                        mUpdateLock.release();
1762                    }
1763                }
1764                break;
1765            }
1766            case PERSIST_URI_GRANTS_MSG: {
1767                writeGrantedUriPermissions();
1768                break;
1769            }
1770            case REQUEST_ALL_PSS_MSG: {
1771                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1772                break;
1773            }
1774            case START_PROFILES_MSG: {
1775                synchronized (ActivityManagerService.this) {
1776                    startProfilesLocked();
1777                }
1778                break;
1779            }
1780            case UPDATE_TIME: {
1781                synchronized (ActivityManagerService.this) {
1782                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1783                        ProcessRecord r = mLruProcesses.get(i);
1784                        if (r.thread != null) {
1785                            try {
1786                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1787                            } catch (RemoteException ex) {
1788                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1789                            }
1790                        }
1791                    }
1792                }
1793                break;
1794            }
1795            case SYSTEM_USER_START_MSG: {
1796                mSystemServiceManager.startUser(msg.arg1);
1797                break;
1798            }
1799            case SYSTEM_USER_CURRENT_MSG: {
1800                mSystemServiceManager.switchUser(msg.arg1);
1801                break;
1802            }
1803            }
1804        }
1805    };
1806
1807    static final int COLLECT_PSS_BG_MSG = 1;
1808
1809    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1810        @Override
1811        public void handleMessage(Message msg) {
1812            switch (msg.what) {
1813            case COLLECT_PSS_BG_MSG: {
1814                long start = SystemClock.uptimeMillis();
1815                MemInfoReader memInfo = null;
1816                synchronized (ActivityManagerService.this) {
1817                    if (mFullPssPending) {
1818                        mFullPssPending = false;
1819                        memInfo = new MemInfoReader();
1820                    }
1821                }
1822                if (memInfo != null) {
1823                    updateCpuStatsNow();
1824                    long nativeTotalPss = 0;
1825                    synchronized (mProcessCpuThread) {
1826                        final int N = mProcessCpuTracker.countStats();
1827                        for (int j=0; j<N; j++) {
1828                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1829                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1830                                // This is definitely an application process; skip it.
1831                                continue;
1832                            }
1833                            synchronized (mPidsSelfLocked) {
1834                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1835                                    // This is one of our own processes; skip it.
1836                                    continue;
1837                                }
1838                            }
1839                            nativeTotalPss += Debug.getPss(st.pid, null);
1840                        }
1841                    }
1842                    memInfo.readMemInfo();
1843                    synchronized (this) {
1844                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1845                                + (SystemClock.uptimeMillis()-start) + "ms");
1846                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1847                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1848                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1849                                        +memInfo.getSlabSizeKb(),
1850                                nativeTotalPss);
1851                    }
1852                }
1853
1854                int i=0, num=0;
1855                long[] tmp = new long[1];
1856                do {
1857                    ProcessRecord proc;
1858                    int procState;
1859                    int pid;
1860                    synchronized (ActivityManagerService.this) {
1861                        if (i >= mPendingPssProcesses.size()) {
1862                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1863                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1864                            mPendingPssProcesses.clear();
1865                            return;
1866                        }
1867                        proc = mPendingPssProcesses.get(i);
1868                        procState = proc.pssProcState;
1869                        if (proc.thread != null && procState == proc.setProcState) {
1870                            pid = proc.pid;
1871                        } else {
1872                            proc = null;
1873                            pid = 0;
1874                        }
1875                        i++;
1876                    }
1877                    if (proc != null) {
1878                        long pss = Debug.getPss(pid, tmp);
1879                        synchronized (ActivityManagerService.this) {
1880                            if (proc.thread != null && proc.setProcState == procState
1881                                    && proc.pid == pid) {
1882                                num++;
1883                                proc.lastPssTime = SystemClock.uptimeMillis();
1884                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1885                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1886                                        + ": " + pss + " lastPss=" + proc.lastPss
1887                                        + " state=" + ProcessList.makeProcStateString(procState));
1888                                if (proc.initialIdlePss == 0) {
1889                                    proc.initialIdlePss = pss;
1890                                }
1891                                proc.lastPss = pss;
1892                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1893                                    proc.lastCachedPss = pss;
1894                                }
1895                            }
1896                        }
1897                    }
1898                } while (true);
1899            }
1900            }
1901        }
1902    };
1903
1904    /**
1905     * Monitor for package changes and update our internal state.
1906     */
1907    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1908        @Override
1909        public void onPackageRemoved(String packageName, int uid) {
1910            // Remove all tasks with activities in the specified package from the list of recent tasks
1911            synchronized (ActivityManagerService.this) {
1912                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1913                    TaskRecord tr = mRecentTasks.get(i);
1914                    ComponentName cn = tr.intent.getComponent();
1915                    if (cn != null && cn.getPackageName().equals(packageName)) {
1916                        // If the package name matches, remove the task and kill the process
1917                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1918                    }
1919                }
1920            }
1921        }
1922
1923        @Override
1924        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1925            onPackageModified(packageName);
1926            return true;
1927        }
1928
1929        @Override
1930        public void onPackageModified(String packageName) {
1931            final PackageManager pm = mContext.getPackageManager();
1932            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1933                    new ArrayList<Pair<Intent, Integer>>();
1934            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1935            // Copy the list of recent tasks so that we don't hold onto the lock on
1936            // ActivityManagerService for long periods while checking if components exist.
1937            synchronized (ActivityManagerService.this) {
1938                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1939                    TaskRecord tr = mRecentTasks.get(i);
1940                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1941                }
1942            }
1943            // Check the recent tasks and filter out all tasks with components that no longer exist.
1944            Intent tmpI = new Intent();
1945            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1946                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1947                ComponentName cn = p.first.getComponent();
1948                if (cn != null && cn.getPackageName().equals(packageName)) {
1949                    try {
1950                        // Add the task to the list to remove if the component no longer exists
1951                        tmpI.setComponent(cn);
1952                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1953                            tasksToRemove.add(p.second);
1954                        }
1955                    } catch (Exception e) {}
1956                }
1957            }
1958            // Prune all the tasks with removed components from the list of recent tasks
1959            synchronized (ActivityManagerService.this) {
1960                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1961                    // Remove the task but don't kill the process (since other components in that
1962                    // package may still be running and in the background)
1963                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1964                }
1965            }
1966        }
1967
1968        @Override
1969        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1970            // Force stop the specified packages
1971            if (packages != null) {
1972                for (String pkg : packages) {
1973                    synchronized (ActivityManagerService.this) {
1974                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1975                                "finished booting")) {
1976                            return true;
1977                        }
1978                    }
1979                }
1980            }
1981            return false;
1982        }
1983    };
1984
1985    public void setSystemProcess() {
1986        try {
1987            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1988            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1989            ServiceManager.addService("meminfo", new MemBinder(this));
1990            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1991            ServiceManager.addService("dbinfo", new DbBinder(this));
1992            if (MONITOR_CPU_USAGE) {
1993                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1994            }
1995            ServiceManager.addService("permission", new PermissionController(this));
1996
1997            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1998                    "android", STOCK_PM_FLAGS);
1999            mSystemThread.installSystemApplicationInfo(info);
2000
2001            synchronized (this) {
2002                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2003                app.persistent = true;
2004                app.pid = MY_PID;
2005                app.maxAdj = ProcessList.SYSTEM_ADJ;
2006                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2007                mProcessNames.put(app.processName, app.uid, app);
2008                synchronized (mPidsSelfLocked) {
2009                    mPidsSelfLocked.put(app.pid, app);
2010                }
2011                updateLruProcessLocked(app, false, null);
2012                updateOomAdjLocked();
2013            }
2014        } catch (PackageManager.NameNotFoundException e) {
2015            throw new RuntimeException(
2016                    "Unable to find android system package", e);
2017        }
2018    }
2019
2020    public void setWindowManager(WindowManagerService wm) {
2021        mWindowManager = wm;
2022        mStackSupervisor.setWindowManager(wm);
2023    }
2024
2025    public void startObservingNativeCrashes() {
2026        final NativeCrashListener ncl = new NativeCrashListener(this);
2027        ncl.start();
2028    }
2029
2030    public IAppOpsService getAppOpsService() {
2031        return mAppOpsService;
2032    }
2033
2034    static class MemBinder extends Binder {
2035        ActivityManagerService mActivityManagerService;
2036        MemBinder(ActivityManagerService activityManagerService) {
2037            mActivityManagerService = activityManagerService;
2038        }
2039
2040        @Override
2041        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2042            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2043                    != PackageManager.PERMISSION_GRANTED) {
2044                pw.println("Permission Denial: can't dump meminfo from from pid="
2045                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2046                        + " without permission " + android.Manifest.permission.DUMP);
2047                return;
2048            }
2049
2050            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2051        }
2052    }
2053
2054    static class GraphicsBinder extends Binder {
2055        ActivityManagerService mActivityManagerService;
2056        GraphicsBinder(ActivityManagerService activityManagerService) {
2057            mActivityManagerService = activityManagerService;
2058        }
2059
2060        @Override
2061        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2062            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2063                    != PackageManager.PERMISSION_GRANTED) {
2064                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2065                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2066                        + " without permission " + android.Manifest.permission.DUMP);
2067                return;
2068            }
2069
2070            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2071        }
2072    }
2073
2074    static class DbBinder extends Binder {
2075        ActivityManagerService mActivityManagerService;
2076        DbBinder(ActivityManagerService activityManagerService) {
2077            mActivityManagerService = activityManagerService;
2078        }
2079
2080        @Override
2081        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2082            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2083                    != PackageManager.PERMISSION_GRANTED) {
2084                pw.println("Permission Denial: can't dump dbinfo from from pid="
2085                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2086                        + " without permission " + android.Manifest.permission.DUMP);
2087                return;
2088            }
2089
2090            mActivityManagerService.dumpDbInfo(fd, pw, args);
2091        }
2092    }
2093
2094    static class CpuBinder extends Binder {
2095        ActivityManagerService mActivityManagerService;
2096        CpuBinder(ActivityManagerService activityManagerService) {
2097            mActivityManagerService = activityManagerService;
2098        }
2099
2100        @Override
2101        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2102            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2103                    != PackageManager.PERMISSION_GRANTED) {
2104                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2105                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2106                        + " without permission " + android.Manifest.permission.DUMP);
2107                return;
2108            }
2109
2110            synchronized (mActivityManagerService.mProcessCpuThread) {
2111                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2112                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2113                        SystemClock.uptimeMillis()));
2114            }
2115        }
2116    }
2117
2118    public static final class Lifecycle extends SystemService {
2119        private final ActivityManagerService mService;
2120
2121        public Lifecycle(Context context) {
2122            super(context);
2123            mService = new ActivityManagerService(context);
2124        }
2125
2126        @Override
2127        public void onStart() {
2128            mService.start();
2129        }
2130
2131        public ActivityManagerService getService() {
2132            return mService;
2133        }
2134    }
2135
2136    // Note: This method is invoked on the main thread but may need to attach various
2137    // handlers to other threads.  So take care to be explicit about the looper.
2138    public ActivityManagerService(Context systemContext) {
2139        mContext = systemContext;
2140        mFactoryTest = FactoryTest.getMode();
2141        mSystemThread = ActivityThread.currentActivityThread();
2142
2143        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2144
2145        mHandlerThread = new ServiceThread(TAG,
2146                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2147        mHandlerThread.start();
2148        mHandler = new MainHandler(mHandlerThread.getLooper());
2149
2150        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2151                "foreground", BROADCAST_FG_TIMEOUT, false);
2152        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2153                "background", BROADCAST_BG_TIMEOUT, true);
2154        mBroadcastQueues[0] = mFgBroadcastQueue;
2155        mBroadcastQueues[1] = mBgBroadcastQueue;
2156
2157        mServices = new ActiveServices(this);
2158        mProviderMap = new ProviderMap(this);
2159
2160        // TODO: Move creation of battery stats service outside of activity manager service.
2161        File dataDir = Environment.getDataDirectory();
2162        File systemDir = new File(dataDir, "system");
2163        systemDir.mkdirs();
2164        mBatteryStatsService = new BatteryStatsService(new File(
2165                systemDir, "batterystats.bin").toString(), mHandler);
2166        mBatteryStatsService.getActiveStatistics().readLocked();
2167        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2168        mOnBattery = DEBUG_POWER ? true
2169                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2170        mBatteryStatsService.getActiveStatistics().setCallback(this);
2171
2172        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2173
2174        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2175        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2176
2177        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2178
2179        // User 0 is the first and only user that runs at boot.
2180        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2181        mUserLru.add(Integer.valueOf(0));
2182        updateStartedUserArrayLocked();
2183
2184        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2185            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2186
2187        mConfiguration.setToDefaults();
2188        mConfiguration.setLocale(Locale.getDefault());
2189
2190        mConfigurationSeq = mConfiguration.seq = 1;
2191        mProcessCpuTracker.init();
2192
2193        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2194        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2195        mStackSupervisor = new ActivityStackSupervisor(this);
2196        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2197
2198        mProcessCpuThread = new Thread("CpuTracker") {
2199            @Override
2200            public void run() {
2201                while (true) {
2202                    try {
2203                        try {
2204                            synchronized(this) {
2205                                final long now = SystemClock.uptimeMillis();
2206                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2207                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2208                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2209                                //        + ", write delay=" + nextWriteDelay);
2210                                if (nextWriteDelay < nextCpuDelay) {
2211                                    nextCpuDelay = nextWriteDelay;
2212                                }
2213                                if (nextCpuDelay > 0) {
2214                                    mProcessCpuMutexFree.set(true);
2215                                    this.wait(nextCpuDelay);
2216                                }
2217                            }
2218                        } catch (InterruptedException e) {
2219                        }
2220                        updateCpuStatsNow();
2221                    } catch (Exception e) {
2222                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2223                    }
2224                }
2225            }
2226        };
2227
2228        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2229
2230        Watchdog.getInstance().addMonitor(this);
2231        Watchdog.getInstance().addThread(mHandler);
2232    }
2233
2234    public void setSystemServiceManager(SystemServiceManager mgr) {
2235        mSystemServiceManager = mgr;
2236    }
2237
2238    private void start() {
2239        Process.removeAllProcessGroups();
2240        mProcessCpuThread.start();
2241
2242        mBatteryStatsService.publish(mContext);
2243        mUsageStatsService.publish(mContext);
2244        mAppOpsService.publish(mContext);
2245        Slog.d("AppOps", "AppOpsService published");
2246        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2247    }
2248
2249    public void initPowerManagement() {
2250        mStackSupervisor.initPowerManagement();
2251        mBatteryStatsService.initPowerManagement();
2252    }
2253
2254    @Override
2255    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2256            throws RemoteException {
2257        if (code == SYSPROPS_TRANSACTION) {
2258            // We need to tell all apps about the system property change.
2259            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2260            synchronized(this) {
2261                final int NP = mProcessNames.getMap().size();
2262                for (int ip=0; ip<NP; ip++) {
2263                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2264                    final int NA = apps.size();
2265                    for (int ia=0; ia<NA; ia++) {
2266                        ProcessRecord app = apps.valueAt(ia);
2267                        if (app.thread != null) {
2268                            procs.add(app.thread.asBinder());
2269                        }
2270                    }
2271                }
2272            }
2273
2274            int N = procs.size();
2275            for (int i=0; i<N; i++) {
2276                Parcel data2 = Parcel.obtain();
2277                try {
2278                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2279                } catch (RemoteException e) {
2280                }
2281                data2.recycle();
2282            }
2283        }
2284        try {
2285            return super.onTransact(code, data, reply, flags);
2286        } catch (RuntimeException e) {
2287            // The activity manager only throws security exceptions, so let's
2288            // log all others.
2289            if (!(e instanceof SecurityException)) {
2290                Slog.wtf(TAG, "Activity Manager Crash", e);
2291            }
2292            throw e;
2293        }
2294    }
2295
2296    void updateCpuStats() {
2297        final long now = SystemClock.uptimeMillis();
2298        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2299            return;
2300        }
2301        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2302            synchronized (mProcessCpuThread) {
2303                mProcessCpuThread.notify();
2304            }
2305        }
2306    }
2307
2308    void updateCpuStatsNow() {
2309        synchronized (mProcessCpuThread) {
2310            mProcessCpuMutexFree.set(false);
2311            final long now = SystemClock.uptimeMillis();
2312            boolean haveNewCpuStats = false;
2313
2314            if (MONITOR_CPU_USAGE &&
2315                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2316                mLastCpuTime.set(now);
2317                haveNewCpuStats = true;
2318                mProcessCpuTracker.update();
2319                //Slog.i(TAG, mProcessCpu.printCurrentState());
2320                //Slog.i(TAG, "Total CPU usage: "
2321                //        + mProcessCpu.getTotalCpuPercent() + "%");
2322
2323                // Slog the cpu usage if the property is set.
2324                if ("true".equals(SystemProperties.get("events.cpu"))) {
2325                    int user = mProcessCpuTracker.getLastUserTime();
2326                    int system = mProcessCpuTracker.getLastSystemTime();
2327                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2328                    int irq = mProcessCpuTracker.getLastIrqTime();
2329                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2330                    int idle = mProcessCpuTracker.getLastIdleTime();
2331
2332                    int total = user + system + iowait + irq + softIrq + idle;
2333                    if (total == 0) total = 1;
2334
2335                    EventLog.writeEvent(EventLogTags.CPU,
2336                            ((user+system+iowait+irq+softIrq) * 100) / total,
2337                            (user * 100) / total,
2338                            (system * 100) / total,
2339                            (iowait * 100) / total,
2340                            (irq * 100) / total,
2341                            (softIrq * 100) / total);
2342                }
2343            }
2344
2345            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2346            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2347            synchronized(bstats) {
2348                synchronized(mPidsSelfLocked) {
2349                    if (haveNewCpuStats) {
2350                        if (mOnBattery) {
2351                            int perc = bstats.startAddingCpuLocked();
2352                            int totalUTime = 0;
2353                            int totalSTime = 0;
2354                            final int N = mProcessCpuTracker.countStats();
2355                            for (int i=0; i<N; i++) {
2356                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2357                                if (!st.working) {
2358                                    continue;
2359                                }
2360                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2361                                int otherUTime = (st.rel_utime*perc)/100;
2362                                int otherSTime = (st.rel_stime*perc)/100;
2363                                totalUTime += otherUTime;
2364                                totalSTime += otherSTime;
2365                                if (pr != null) {
2366                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2367                                    if (ps == null || !ps.isActive()) {
2368                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2369                                                pr.info.uid, pr.processName);
2370                                    }
2371                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2372                                            st.rel_stime-otherSTime);
2373                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2374                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2375                                } else {
2376                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2377                                    if (ps == null || !ps.isActive()) {
2378                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2379                                                bstats.mapUid(st.uid), st.name);
2380                                    }
2381                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2382                                            st.rel_stime-otherSTime);
2383                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2384                                }
2385                            }
2386                            bstats.finishAddingCpuLocked(perc, totalUTime,
2387                                    totalSTime, cpuSpeedTimes);
2388                        }
2389                    }
2390                }
2391
2392                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2393                    mLastWriteTime = now;
2394                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2395                }
2396            }
2397        }
2398    }
2399
2400    @Override
2401    public void batteryNeedsCpuUpdate() {
2402        updateCpuStatsNow();
2403    }
2404
2405    @Override
2406    public void batteryPowerChanged(boolean onBattery) {
2407        // When plugging in, update the CPU stats first before changing
2408        // the plug state.
2409        updateCpuStatsNow();
2410        synchronized (this) {
2411            synchronized(mPidsSelfLocked) {
2412                mOnBattery = DEBUG_POWER ? true : onBattery;
2413            }
2414        }
2415    }
2416
2417    /**
2418     * Initialize the application bind args. These are passed to each
2419     * process when the bindApplication() IPC is sent to the process. They're
2420     * lazily setup to make sure the services are running when they're asked for.
2421     */
2422    private HashMap<String, IBinder> getCommonServicesLocked() {
2423        if (mAppBindArgs == null) {
2424            mAppBindArgs = new HashMap<String, IBinder>();
2425
2426            // Setup the application init args
2427            mAppBindArgs.put("package", ServiceManager.getService("package"));
2428            mAppBindArgs.put("window", ServiceManager.getService("window"));
2429            mAppBindArgs.put(Context.ALARM_SERVICE,
2430                    ServiceManager.getService(Context.ALARM_SERVICE));
2431        }
2432        return mAppBindArgs;
2433    }
2434
2435    final void setFocusedActivityLocked(ActivityRecord r) {
2436        if (mFocusedActivity != r) {
2437            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2438            mFocusedActivity = r;
2439            if (r.task != null && r.task.voiceInteractor != null) {
2440                startRunningVoiceLocked();
2441            } else {
2442                finishRunningVoiceLocked();
2443            }
2444            mStackSupervisor.setFocusedStack(r);
2445            if (r != null) {
2446                mWindowManager.setFocusedApp(r.appToken, true);
2447            }
2448            applyUpdateLockStateLocked(r);
2449        }
2450    }
2451
2452    final void clearFocusedActivity(ActivityRecord r) {
2453        if (mFocusedActivity == r) {
2454            mFocusedActivity = null;
2455        }
2456    }
2457
2458    @Override
2459    public void setFocusedStack(int stackId) {
2460        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2461        synchronized (ActivityManagerService.this) {
2462            ActivityStack stack = mStackSupervisor.getStack(stackId);
2463            if (stack != null) {
2464                ActivityRecord r = stack.topRunningActivityLocked(null);
2465                if (r != null) {
2466                    setFocusedActivityLocked(r);
2467                }
2468            }
2469        }
2470    }
2471
2472    @Override
2473    public void notifyActivityDrawn(IBinder token) {
2474        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2475        synchronized (this) {
2476            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2477            if (r != null) {
2478                r.task.stack.notifyActivityDrawnLocked(r);
2479            }
2480        }
2481    }
2482
2483    final void applyUpdateLockStateLocked(ActivityRecord r) {
2484        // Modifications to the UpdateLock state are done on our handler, outside
2485        // the activity manager's locks.  The new state is determined based on the
2486        // state *now* of the relevant activity record.  The object is passed to
2487        // the handler solely for logging detail, not to be consulted/modified.
2488        final boolean nextState = r != null && r.immersive;
2489        mHandler.sendMessage(
2490                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2491    }
2492
2493    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2494        Message msg = Message.obtain();
2495        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2496        msg.obj = r.task.askedCompatMode ? null : r;
2497        mHandler.sendMessage(msg);
2498    }
2499
2500    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2501            String what, Object obj, ProcessRecord srcApp) {
2502        app.lastActivityTime = now;
2503
2504        if (app.activities.size() > 0) {
2505            // Don't want to touch dependent processes that are hosting activities.
2506            return index;
2507        }
2508
2509        int lrui = mLruProcesses.lastIndexOf(app);
2510        if (lrui < 0) {
2511            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2512                    + what + " " + obj + " from " + srcApp);
2513            return index;
2514        }
2515
2516        if (lrui >= index) {
2517            // Don't want to cause this to move dependent processes *back* in the
2518            // list as if they were less frequently used.
2519            return index;
2520        }
2521
2522        if (lrui >= mLruProcessActivityStart) {
2523            // Don't want to touch dependent processes that are hosting activities.
2524            return index;
2525        }
2526
2527        mLruProcesses.remove(lrui);
2528        if (index > 0) {
2529            index--;
2530        }
2531        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2532                + " in LRU list: " + app);
2533        mLruProcesses.add(index, app);
2534        return index;
2535    }
2536
2537    final void removeLruProcessLocked(ProcessRecord app) {
2538        int lrui = mLruProcesses.lastIndexOf(app);
2539        if (lrui >= 0) {
2540            if (lrui <= mLruProcessActivityStart) {
2541                mLruProcessActivityStart--;
2542            }
2543            if (lrui <= mLruProcessServiceStart) {
2544                mLruProcessServiceStart--;
2545            }
2546            mLruProcesses.remove(lrui);
2547        }
2548    }
2549
2550    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2551            ProcessRecord client) {
2552        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2553                || app.treatLikeActivity;
2554        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2555        if (!activityChange && hasActivity) {
2556            // The process has activities, so we are only allowing activity-based adjustments
2557            // to move it.  It should be kept in the front of the list with other
2558            // processes that have activities, and we don't want those to change their
2559            // order except due to activity operations.
2560            return;
2561        }
2562
2563        mLruSeq++;
2564        final long now = SystemClock.uptimeMillis();
2565        app.lastActivityTime = now;
2566
2567        // First a quick reject: if the app is already at the position we will
2568        // put it, then there is nothing to do.
2569        if (hasActivity) {
2570            final int N = mLruProcesses.size();
2571            if (N > 0 && mLruProcesses.get(N-1) == app) {
2572                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2573                return;
2574            }
2575        } else {
2576            if (mLruProcessServiceStart > 0
2577                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2578                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2579                return;
2580            }
2581        }
2582
2583        int lrui = mLruProcesses.lastIndexOf(app);
2584
2585        if (app.persistent && lrui >= 0) {
2586            // We don't care about the position of persistent processes, as long as
2587            // they are in the list.
2588            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2589            return;
2590        }
2591
2592        /* In progress: compute new position first, so we can avoid doing work
2593           if the process is not actually going to move.  Not yet working.
2594        int addIndex;
2595        int nextIndex;
2596        boolean inActivity = false, inService = false;
2597        if (hasActivity) {
2598            // Process has activities, put it at the very tipsy-top.
2599            addIndex = mLruProcesses.size();
2600            nextIndex = mLruProcessServiceStart;
2601            inActivity = true;
2602        } else if (hasService) {
2603            // Process has services, put it at the top of the service list.
2604            addIndex = mLruProcessActivityStart;
2605            nextIndex = mLruProcessServiceStart;
2606            inActivity = true;
2607            inService = true;
2608        } else  {
2609            // Process not otherwise of interest, it goes to the top of the non-service area.
2610            addIndex = mLruProcessServiceStart;
2611            if (client != null) {
2612                int clientIndex = mLruProcesses.lastIndexOf(client);
2613                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2614                        + app);
2615                if (clientIndex >= 0 && addIndex > clientIndex) {
2616                    addIndex = clientIndex;
2617                }
2618            }
2619            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2620        }
2621
2622        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2623                + mLruProcessActivityStart + "): " + app);
2624        */
2625
2626        if (lrui >= 0) {
2627            if (lrui < mLruProcessActivityStart) {
2628                mLruProcessActivityStart--;
2629            }
2630            if (lrui < mLruProcessServiceStart) {
2631                mLruProcessServiceStart--;
2632            }
2633            /*
2634            if (addIndex > lrui) {
2635                addIndex--;
2636            }
2637            if (nextIndex > lrui) {
2638                nextIndex--;
2639            }
2640            */
2641            mLruProcesses.remove(lrui);
2642        }
2643
2644        /*
2645        mLruProcesses.add(addIndex, app);
2646        if (inActivity) {
2647            mLruProcessActivityStart++;
2648        }
2649        if (inService) {
2650            mLruProcessActivityStart++;
2651        }
2652        */
2653
2654        int nextIndex;
2655        if (hasActivity) {
2656            final int N = mLruProcesses.size();
2657            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2658                // Process doesn't have activities, but has clients with
2659                // activities...  move it up, but one below the top (the top
2660                // should always have a real activity).
2661                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2662                mLruProcesses.add(N-1, app);
2663                // To keep it from spamming the LRU list (by making a bunch of clients),
2664                // we will push down any other entries owned by the app.
2665                final int uid = app.info.uid;
2666                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2667                    ProcessRecord subProc = mLruProcesses.get(i);
2668                    if (subProc.info.uid == uid) {
2669                        // We want to push this one down the list.  If the process after
2670                        // it is for the same uid, however, don't do so, because we don't
2671                        // want them internally to be re-ordered.
2672                        if (mLruProcesses.get(i-1).info.uid != uid) {
2673                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2674                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2675                            ProcessRecord tmp = mLruProcesses.get(i);
2676                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2677                            mLruProcesses.set(i-1, tmp);
2678                            i--;
2679                        }
2680                    } else {
2681                        // A gap, we can stop here.
2682                        break;
2683                    }
2684                }
2685            } else {
2686                // Process has activities, put it at the very tipsy-top.
2687                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2688                mLruProcesses.add(app);
2689            }
2690            nextIndex = mLruProcessServiceStart;
2691        } else if (hasService) {
2692            // Process has services, put it at the top of the service list.
2693            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2694            mLruProcesses.add(mLruProcessActivityStart, app);
2695            nextIndex = mLruProcessServiceStart;
2696            mLruProcessActivityStart++;
2697        } else  {
2698            // Process not otherwise of interest, it goes to the top of the non-service area.
2699            int index = mLruProcessServiceStart;
2700            if (client != null) {
2701                // If there is a client, don't allow the process to be moved up higher
2702                // in the list than that client.
2703                int clientIndex = mLruProcesses.lastIndexOf(client);
2704                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2705                        + " when updating " + app);
2706                if (clientIndex <= lrui) {
2707                    // Don't allow the client index restriction to push it down farther in the
2708                    // list than it already is.
2709                    clientIndex = lrui;
2710                }
2711                if (clientIndex >= 0 && index > clientIndex) {
2712                    index = clientIndex;
2713                }
2714            }
2715            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2716            mLruProcesses.add(index, app);
2717            nextIndex = index-1;
2718            mLruProcessActivityStart++;
2719            mLruProcessServiceStart++;
2720        }
2721
2722        // If the app is currently using a content provider or service,
2723        // bump those processes as well.
2724        for (int j=app.connections.size()-1; j>=0; j--) {
2725            ConnectionRecord cr = app.connections.valueAt(j);
2726            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2727                    && cr.binding.service.app != null
2728                    && cr.binding.service.app.lruSeq != mLruSeq
2729                    && !cr.binding.service.app.persistent) {
2730                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2731                        "service connection", cr, app);
2732            }
2733        }
2734        for (int j=app.conProviders.size()-1; j>=0; j--) {
2735            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2736            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2737                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2738                        "provider reference", cpr, app);
2739            }
2740        }
2741    }
2742
2743    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2744        if (uid == Process.SYSTEM_UID) {
2745            // The system gets to run in any process.  If there are multiple
2746            // processes with the same uid, just pick the first (this
2747            // should never happen).
2748            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2749            if (procs == null) return null;
2750            final int N = procs.size();
2751            for (int i = 0; i < N; i++) {
2752                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2753            }
2754        }
2755        ProcessRecord proc = mProcessNames.get(processName, uid);
2756        if (false && proc != null && !keepIfLarge
2757                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2758                && proc.lastCachedPss >= 4000) {
2759            // Turn this condition on to cause killing to happen regularly, for testing.
2760            if (proc.baseProcessTracker != null) {
2761                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2762            }
2763            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2764                    + "k from cached");
2765        } else if (proc != null && !keepIfLarge
2766                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2767                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2768            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2769            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2770                if (proc.baseProcessTracker != null) {
2771                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2772                }
2773                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2774                        + "k from cached");
2775            }
2776        }
2777        return proc;
2778    }
2779
2780    void ensurePackageDexOpt(String packageName) {
2781        IPackageManager pm = AppGlobals.getPackageManager();
2782        try {
2783            if (pm.performDexOpt(packageName)) {
2784                mDidDexOpt = true;
2785            }
2786        } catch (RemoteException e) {
2787        }
2788    }
2789
2790    boolean isNextTransitionForward() {
2791        int transit = mWindowManager.getPendingAppTransition();
2792        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2793                || transit == AppTransition.TRANSIT_TASK_OPEN
2794                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2795    }
2796
2797    final ProcessRecord startProcessLocked(String processName,
2798            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2799            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2800            boolean isolated, boolean keepIfLarge) {
2801        ProcessRecord app;
2802        if (!isolated) {
2803            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2804        } else {
2805            // If this is an isolated process, it can't re-use an existing process.
2806            app = null;
2807        }
2808        // We don't have to do anything more if:
2809        // (1) There is an existing application record; and
2810        // (2) The caller doesn't think it is dead, OR there is no thread
2811        //     object attached to it so we know it couldn't have crashed; and
2812        // (3) There is a pid assigned to it, so it is either starting or
2813        //     already running.
2814        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2815                + " app=" + app + " knownToBeDead=" + knownToBeDead
2816                + " thread=" + (app != null ? app.thread : null)
2817                + " pid=" + (app != null ? app.pid : -1));
2818        if (app != null && app.pid > 0) {
2819            if (!knownToBeDead || app.thread == null) {
2820                // We already have the app running, or are waiting for it to
2821                // come up (we have a pid but not yet its thread), so keep it.
2822                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2823                // If this is a new package in the process, add the package to the list
2824                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2825                return app;
2826            }
2827
2828            // An application record is attached to a previous process,
2829            // clean it up now.
2830            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2831            Process.killProcessGroup(app.info.uid, app.pid);
2832            handleAppDiedLocked(app, true, true);
2833        }
2834
2835        String hostingNameStr = hostingName != null
2836                ? hostingName.flattenToShortString() : null;
2837
2838        if (!isolated) {
2839            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2840                // If we are in the background, then check to see if this process
2841                // is bad.  If so, we will just silently fail.
2842                if (mBadProcesses.get(info.processName, info.uid) != null) {
2843                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2844                            + "/" + info.processName);
2845                    return null;
2846                }
2847            } else {
2848                // When the user is explicitly starting a process, then clear its
2849                // crash count so that we won't make it bad until they see at
2850                // least one crash dialog again, and make the process good again
2851                // if it had been bad.
2852                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2853                        + "/" + info.processName);
2854                mProcessCrashTimes.remove(info.processName, info.uid);
2855                if (mBadProcesses.get(info.processName, info.uid) != null) {
2856                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2857                            UserHandle.getUserId(info.uid), info.uid,
2858                            info.processName);
2859                    mBadProcesses.remove(info.processName, info.uid);
2860                    if (app != null) {
2861                        app.bad = false;
2862                    }
2863                }
2864            }
2865        }
2866
2867        if (app == null) {
2868            app = newProcessRecordLocked(info, processName, isolated);
2869            if (app == null) {
2870                Slog.w(TAG, "Failed making new process record for "
2871                        + processName + "/" + info.uid + " isolated=" + isolated);
2872                return null;
2873            }
2874            mProcessNames.put(processName, app.uid, app);
2875            if (isolated) {
2876                mIsolatedProcesses.put(app.uid, app);
2877            }
2878        } else {
2879            // If this is a new package in the process, add the package to the list
2880            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2881        }
2882
2883        // If the system is not ready yet, then hold off on starting this
2884        // process until it is.
2885        if (!mProcessesReady
2886                && !isAllowedWhileBooting(info)
2887                && !allowWhileBooting) {
2888            if (!mProcessesOnHold.contains(app)) {
2889                mProcessesOnHold.add(app);
2890            }
2891            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2892            return app;
2893        }
2894
2895        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2896        return (app.pid != 0) ? app : null;
2897    }
2898
2899    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2900        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2901    }
2902
2903    private final void startProcessLocked(ProcessRecord app,
2904            String hostingType, String hostingNameStr, String abiOverride) {
2905        if (app.pid > 0 && app.pid != MY_PID) {
2906            synchronized (mPidsSelfLocked) {
2907                mPidsSelfLocked.remove(app.pid);
2908                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2909            }
2910            app.setPid(0);
2911        }
2912
2913        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2914                "startProcessLocked removing on hold: " + app);
2915        mProcessesOnHold.remove(app);
2916
2917        updateCpuStats();
2918
2919        try {
2920            int uid = app.uid;
2921
2922            int[] gids = null;
2923            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2924            if (!app.isolated) {
2925                int[] permGids = null;
2926                try {
2927                    final PackageManager pm = mContext.getPackageManager();
2928                    permGids = pm.getPackageGids(app.info.packageName);
2929
2930                    if (Environment.isExternalStorageEmulated()) {
2931                        if (pm.checkPermission(
2932                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2933                                app.info.packageName) == PERMISSION_GRANTED) {
2934                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2935                        } else {
2936                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2937                        }
2938                    }
2939                } catch (PackageManager.NameNotFoundException e) {
2940                    Slog.w(TAG, "Unable to retrieve gids", e);
2941                }
2942
2943                /*
2944                 * Add shared application and profile GIDs so applications can share some
2945                 * resources like shared libraries and access user-wide resources
2946                 */
2947                if (permGids == null) {
2948                    gids = new int[2];
2949                } else {
2950                    gids = new int[permGids.length + 2];
2951                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2952                }
2953                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2954                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2955            }
2956            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2957                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2958                        && mTopComponent != null
2959                        && app.processName.equals(mTopComponent.getPackageName())) {
2960                    uid = 0;
2961                }
2962                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2963                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2964                    uid = 0;
2965                }
2966            }
2967            int debugFlags = 0;
2968            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2969                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2970                // Also turn on CheckJNI for debuggable apps. It's quite
2971                // awkward to turn on otherwise.
2972                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2973            }
2974            // Run the app in safe mode if its manifest requests so or the
2975            // system is booted in safe mode.
2976            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2977                mSafeMode == true) {
2978                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2979            }
2980            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2981                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2982            }
2983            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2984                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2985            }
2986            if ("1".equals(SystemProperties.get("debug.assert"))) {
2987                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2988            }
2989
2990            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2991            if (requiredAbi == null) {
2992                requiredAbi = Build.SUPPORTED_ABIS[0];
2993            }
2994
2995            // Start the process.  It will either succeed and return a result containing
2996            // the PID of the new process, or else throw a RuntimeException.
2997            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2998                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2999                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3000
3001            if (app.isolated) {
3002                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3003            }
3004            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3005
3006            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3007                    UserHandle.getUserId(uid), startResult.pid, uid,
3008                    app.processName, hostingType,
3009                    hostingNameStr != null ? hostingNameStr : "");
3010
3011            if (app.persistent) {
3012                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3013            }
3014
3015            StringBuilder buf = mStringBuilder;
3016            buf.setLength(0);
3017            buf.append("Start proc ");
3018            buf.append(app.processName);
3019            buf.append(" for ");
3020            buf.append(hostingType);
3021            if (hostingNameStr != null) {
3022                buf.append(" ");
3023                buf.append(hostingNameStr);
3024            }
3025            buf.append(": pid=");
3026            buf.append(startResult.pid);
3027            buf.append(" uid=");
3028            buf.append(uid);
3029            buf.append(" gids={");
3030            if (gids != null) {
3031                for (int gi=0; gi<gids.length; gi++) {
3032                    if (gi != 0) buf.append(", ");
3033                    buf.append(gids[gi]);
3034
3035                }
3036            }
3037            buf.append("}");
3038            if (requiredAbi != null) {
3039                buf.append(" abi=");
3040                buf.append(requiredAbi);
3041            }
3042            Slog.i(TAG, buf.toString());
3043            app.setPid(startResult.pid);
3044            app.usingWrapper = startResult.usingWrapper;
3045            app.removed = false;
3046            app.killedByAm = false;
3047            synchronized (mPidsSelfLocked) {
3048                this.mPidsSelfLocked.put(startResult.pid, app);
3049                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3050                msg.obj = app;
3051                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3052                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3053            }
3054        } catch (RuntimeException e) {
3055            // XXX do better error recovery.
3056            app.setPid(0);
3057            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3058            if (app.isolated) {
3059                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3060            }
3061            Slog.e(TAG, "Failure starting process " + app.processName, e);
3062        }
3063    }
3064
3065    void updateUsageStats(ActivityRecord component, boolean resumed) {
3066        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3067        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3068        if (resumed) {
3069            mUsageStatsService.noteResumeComponent(component.realActivity);
3070            synchronized (stats) {
3071                stats.noteActivityResumedLocked(component.app.uid);
3072            }
3073        } else {
3074            mUsageStatsService.notePauseComponent(component.realActivity);
3075            synchronized (stats) {
3076                stats.noteActivityPausedLocked(component.app.uid);
3077            }
3078        }
3079    }
3080
3081    Intent getHomeIntent() {
3082        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3083        intent.setComponent(mTopComponent);
3084        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3085            intent.addCategory(Intent.CATEGORY_HOME);
3086        }
3087        return intent;
3088    }
3089
3090    boolean startHomeActivityLocked(int userId) {
3091        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3092                && mTopAction == null) {
3093            // We are running in factory test mode, but unable to find
3094            // the factory test app, so just sit around displaying the
3095            // error message and don't try to start anything.
3096            return false;
3097        }
3098        Intent intent = getHomeIntent();
3099        ActivityInfo aInfo =
3100            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3101        if (aInfo != null) {
3102            intent.setComponent(new ComponentName(
3103                    aInfo.applicationInfo.packageName, aInfo.name));
3104            // Don't do this if the home app is currently being
3105            // instrumented.
3106            aInfo = new ActivityInfo(aInfo);
3107            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3108            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3109                    aInfo.applicationInfo.uid, true);
3110            if (app == null || app.instrumentationClass == null) {
3111                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3112                mStackSupervisor.startHomeActivity(intent, aInfo);
3113            }
3114        }
3115
3116        return true;
3117    }
3118
3119    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3120        ActivityInfo ai = null;
3121        ComponentName comp = intent.getComponent();
3122        try {
3123            if (comp != null) {
3124                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3125            } else {
3126                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3127                        intent,
3128                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3129                            flags, userId);
3130
3131                if (info != null) {
3132                    ai = info.activityInfo;
3133                }
3134            }
3135        } catch (RemoteException e) {
3136            // ignore
3137        }
3138
3139        return ai;
3140    }
3141
3142    /**
3143     * Starts the "new version setup screen" if appropriate.
3144     */
3145    void startSetupActivityLocked() {
3146        // Only do this once per boot.
3147        if (mCheckedForSetup) {
3148            return;
3149        }
3150
3151        // We will show this screen if the current one is a different
3152        // version than the last one shown, and we are not running in
3153        // low-level factory test mode.
3154        final ContentResolver resolver = mContext.getContentResolver();
3155        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3156                Settings.Global.getInt(resolver,
3157                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3158            mCheckedForSetup = true;
3159
3160            // See if we should be showing the platform update setup UI.
3161            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3162            List<ResolveInfo> ris = mContext.getPackageManager()
3163                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3164
3165            // We don't allow third party apps to replace this.
3166            ResolveInfo ri = null;
3167            for (int i=0; ris != null && i<ris.size(); i++) {
3168                if ((ris.get(i).activityInfo.applicationInfo.flags
3169                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3170                    ri = ris.get(i);
3171                    break;
3172                }
3173            }
3174
3175            if (ri != null) {
3176                String vers = ri.activityInfo.metaData != null
3177                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3178                        : null;
3179                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3180                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3181                            Intent.METADATA_SETUP_VERSION);
3182                }
3183                String lastVers = Settings.Secure.getString(
3184                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3185                if (vers != null && !vers.equals(lastVers)) {
3186                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3187                    intent.setComponent(new ComponentName(
3188                            ri.activityInfo.packageName, ri.activityInfo.name));
3189                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3190                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3191                }
3192            }
3193        }
3194    }
3195
3196    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3197        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3198    }
3199
3200    void enforceNotIsolatedCaller(String caller) {
3201        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3202            throw new SecurityException("Isolated process not allowed to call " + caller);
3203        }
3204    }
3205
3206    @Override
3207    public int getFrontActivityScreenCompatMode() {
3208        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3209        synchronized (this) {
3210            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3211        }
3212    }
3213
3214    @Override
3215    public void setFrontActivityScreenCompatMode(int mode) {
3216        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3217                "setFrontActivityScreenCompatMode");
3218        synchronized (this) {
3219            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3220        }
3221    }
3222
3223    @Override
3224    public int getPackageScreenCompatMode(String packageName) {
3225        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3226        synchronized (this) {
3227            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3228        }
3229    }
3230
3231    @Override
3232    public void setPackageScreenCompatMode(String packageName, int mode) {
3233        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3234                "setPackageScreenCompatMode");
3235        synchronized (this) {
3236            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3237        }
3238    }
3239
3240    @Override
3241    public boolean getPackageAskScreenCompat(String packageName) {
3242        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3243        synchronized (this) {
3244            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3245        }
3246    }
3247
3248    @Override
3249    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3250        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3251                "setPackageAskScreenCompat");
3252        synchronized (this) {
3253            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3254        }
3255    }
3256
3257    private void dispatchProcessesChanged() {
3258        int N;
3259        synchronized (this) {
3260            N = mPendingProcessChanges.size();
3261            if (mActiveProcessChanges.length < N) {
3262                mActiveProcessChanges = new ProcessChangeItem[N];
3263            }
3264            mPendingProcessChanges.toArray(mActiveProcessChanges);
3265            mAvailProcessChanges.addAll(mPendingProcessChanges);
3266            mPendingProcessChanges.clear();
3267            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3268        }
3269
3270        int i = mProcessObservers.beginBroadcast();
3271        while (i > 0) {
3272            i--;
3273            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3274            if (observer != null) {
3275                try {
3276                    for (int j=0; j<N; j++) {
3277                        ProcessChangeItem item = mActiveProcessChanges[j];
3278                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3279                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3280                                    + item.pid + " uid=" + item.uid + ": "
3281                                    + item.foregroundActivities);
3282                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3283                                    item.foregroundActivities);
3284                        }
3285                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3286                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3287                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3288                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3289                        }
3290                    }
3291                } catch (RemoteException e) {
3292                }
3293            }
3294        }
3295        mProcessObservers.finishBroadcast();
3296    }
3297
3298    private void dispatchProcessDied(int pid, int uid) {
3299        int i = mProcessObservers.beginBroadcast();
3300        while (i > 0) {
3301            i--;
3302            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3303            if (observer != null) {
3304                try {
3305                    observer.onProcessDied(pid, uid);
3306                } catch (RemoteException e) {
3307                }
3308            }
3309        }
3310        mProcessObservers.finishBroadcast();
3311    }
3312
3313    final void doPendingActivityLaunchesLocked(boolean doResume) {
3314        final int N = mPendingActivityLaunches.size();
3315        if (N <= 0) {
3316            return;
3317        }
3318        for (int i=0; i<N; i++) {
3319            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3320            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3321                    doResume && i == (N-1), null);
3322        }
3323        mPendingActivityLaunches.clear();
3324    }
3325
3326    @Override
3327    public final int startActivity(IApplicationThread caller, String callingPackage,
3328            Intent intent, String resolvedType, IBinder resultTo,
3329            String resultWho, int requestCode, int startFlags,
3330            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3331        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3332                resultWho, requestCode,
3333                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3334    }
3335
3336    @Override
3337    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3338            Intent intent, String resolvedType, IBinder resultTo,
3339            String resultWho, int requestCode, int startFlags,
3340            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3341        enforceNotIsolatedCaller("startActivity");
3342        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3343                false, true, "startActivity", null);
3344        // TODO: Switch to user app stacks here.
3345        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3346                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3347                null, null, options, userId, null);
3348    }
3349
3350    @Override
3351    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3352            Intent intent, String resolvedType, IBinder resultTo,
3353            String resultWho, int requestCode, int startFlags, String profileFile,
3354            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3355        enforceNotIsolatedCaller("startActivityAndWait");
3356        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3357                false, true, "startActivityAndWait", null);
3358        WaitResult res = new WaitResult();
3359        // TODO: Switch to user app stacks here.
3360        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3361                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3362                res, null, options, UserHandle.getCallingUserId(), null);
3363        return res;
3364    }
3365
3366    @Override
3367    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3368            Intent intent, String resolvedType, IBinder resultTo,
3369            String resultWho, int requestCode, int startFlags, Configuration config,
3370            Bundle options, int userId) {
3371        enforceNotIsolatedCaller("startActivityWithConfig");
3372        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3373                false, true, "startActivityWithConfig", null);
3374        // TODO: Switch to user app stacks here.
3375        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3376                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3377                null, null, null, config, options, userId, null);
3378        return ret;
3379    }
3380
3381    @Override
3382    public int startActivityIntentSender(IApplicationThread caller,
3383            IntentSender intent, Intent fillInIntent, String resolvedType,
3384            IBinder resultTo, String resultWho, int requestCode,
3385            int flagsMask, int flagsValues, Bundle options) {
3386        enforceNotIsolatedCaller("startActivityIntentSender");
3387        // Refuse possible leaked file descriptors
3388        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3389            throw new IllegalArgumentException("File descriptors passed in Intent");
3390        }
3391
3392        IIntentSender sender = intent.getTarget();
3393        if (!(sender instanceof PendingIntentRecord)) {
3394            throw new IllegalArgumentException("Bad PendingIntent object");
3395        }
3396
3397        PendingIntentRecord pir = (PendingIntentRecord)sender;
3398
3399        synchronized (this) {
3400            // If this is coming from the currently resumed activity, it is
3401            // effectively saying that app switches are allowed at this point.
3402            final ActivityStack stack = getFocusedStack();
3403            if (stack.mResumedActivity != null &&
3404                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3405                mAppSwitchesAllowedTime = 0;
3406            }
3407        }
3408        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3409                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3410        return ret;
3411    }
3412
3413    @Override
3414    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3415            Intent intent, String resolvedType, IVoiceInteractionSession session,
3416            IVoiceInteractor interactor, int startFlags, String profileFile,
3417            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3418        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3419                != PackageManager.PERMISSION_GRANTED) {
3420            String msg = "Permission Denial: startVoiceActivity() from pid="
3421                    + Binder.getCallingPid()
3422                    + ", uid=" + Binder.getCallingUid()
3423                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3424            Slog.w(TAG, msg);
3425            throw new SecurityException(msg);
3426        }
3427        if (session == null || interactor == null) {
3428            throw new NullPointerException("null session or interactor");
3429        }
3430        userId = handleIncomingUser(callingPid, callingUid, userId,
3431                false, true, "startVoiceActivity", null);
3432        // TODO: Switch to user app stacks here.
3433        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3434                resolvedType, session, interactor, null, null, 0, startFlags,
3435                profileFile, profileFd, null, null, options, userId, null);
3436    }
3437
3438    @Override
3439    public boolean startNextMatchingActivity(IBinder callingActivity,
3440            Intent intent, Bundle options) {
3441        // Refuse possible leaked file descriptors
3442        if (intent != null && intent.hasFileDescriptors() == true) {
3443            throw new IllegalArgumentException("File descriptors passed in Intent");
3444        }
3445
3446        synchronized (this) {
3447            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3448            if (r == null) {
3449                ActivityOptions.abort(options);
3450                return false;
3451            }
3452            if (r.app == null || r.app.thread == null) {
3453                // The caller is not running...  d'oh!
3454                ActivityOptions.abort(options);
3455                return false;
3456            }
3457            intent = new Intent(intent);
3458            // The caller is not allowed to change the data.
3459            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3460            // And we are resetting to find the next component...
3461            intent.setComponent(null);
3462
3463            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3464
3465            ActivityInfo aInfo = null;
3466            try {
3467                List<ResolveInfo> resolves =
3468                    AppGlobals.getPackageManager().queryIntentActivities(
3469                            intent, r.resolvedType,
3470                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3471                            UserHandle.getCallingUserId());
3472
3473                // Look for the original activity in the list...
3474                final int N = resolves != null ? resolves.size() : 0;
3475                for (int i=0; i<N; i++) {
3476                    ResolveInfo rInfo = resolves.get(i);
3477                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3478                            && rInfo.activityInfo.name.equals(r.info.name)) {
3479                        // We found the current one...  the next matching is
3480                        // after it.
3481                        i++;
3482                        if (i<N) {
3483                            aInfo = resolves.get(i).activityInfo;
3484                        }
3485                        if (debug) {
3486                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3487                                    + "/" + r.info.name);
3488                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3489                                    + "/" + aInfo.name);
3490                        }
3491                        break;
3492                    }
3493                }
3494            } catch (RemoteException e) {
3495            }
3496
3497            if (aInfo == null) {
3498                // Nobody who is next!
3499                ActivityOptions.abort(options);
3500                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3501                return false;
3502            }
3503
3504            intent.setComponent(new ComponentName(
3505                    aInfo.applicationInfo.packageName, aInfo.name));
3506            intent.setFlags(intent.getFlags()&~(
3507                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3508                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3509                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3510                    Intent.FLAG_ACTIVITY_NEW_TASK));
3511
3512            // Okay now we need to start the new activity, replacing the
3513            // currently running activity.  This is a little tricky because
3514            // we want to start the new one as if the current one is finished,
3515            // but not finish the current one first so that there is no flicker.
3516            // And thus...
3517            final boolean wasFinishing = r.finishing;
3518            r.finishing = true;
3519
3520            // Propagate reply information over to the new activity.
3521            final ActivityRecord resultTo = r.resultTo;
3522            final String resultWho = r.resultWho;
3523            final int requestCode = r.requestCode;
3524            r.resultTo = null;
3525            if (resultTo != null) {
3526                resultTo.removeResultsLocked(r, resultWho, requestCode);
3527            }
3528
3529            final long origId = Binder.clearCallingIdentity();
3530            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3531                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3532                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3533                    options, false, null, null);
3534            Binder.restoreCallingIdentity(origId);
3535
3536            r.finishing = wasFinishing;
3537            if (res != ActivityManager.START_SUCCESS) {
3538                return false;
3539            }
3540            return true;
3541        }
3542    }
3543
3544    final int startActivityInPackage(int uid, String callingPackage,
3545            Intent intent, String resolvedType, IBinder resultTo,
3546            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3547                    IActivityContainer container) {
3548
3549        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3550                false, true, "startActivityInPackage", null);
3551
3552        // TODO: Switch to user app stacks here.
3553        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3554                null, null, resultTo, resultWho, requestCode, startFlags,
3555                null, null, null, null, options, userId, container);
3556        return ret;
3557    }
3558
3559    @Override
3560    public final int startActivities(IApplicationThread caller, String callingPackage,
3561            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3562            int userId) {
3563        enforceNotIsolatedCaller("startActivities");
3564        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3565                false, true, "startActivity", null);
3566        // TODO: Switch to user app stacks here.
3567        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3568                resolvedTypes, resultTo, options, userId);
3569        return ret;
3570    }
3571
3572    final int startActivitiesInPackage(int uid, String callingPackage,
3573            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3574            Bundle options, int userId) {
3575
3576        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3577                false, true, "startActivityInPackage", null);
3578        // TODO: Switch to user app stacks here.
3579        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3580                resultTo, options, userId);
3581        return ret;
3582    }
3583
3584    final void addRecentTaskLocked(TaskRecord task) {
3585        int N = mRecentTasks.size();
3586        // Quick case: check if the top-most recent task is the same.
3587        if (N > 0 && mRecentTasks.get(0) == task) {
3588            return;
3589        }
3590        // Another quick case: never add voice sessions.
3591        if (task.voiceSession != null) {
3592            return;
3593        }
3594        // Remove any existing entries that are the same kind of task.
3595        final Intent intent = task.intent;
3596        final boolean document = intent != null && intent.isDocument();
3597        final ComponentName comp = intent.getComponent();
3598
3599        int maxRecents = task.maxRecents - 1;
3600        for (int i=0; i<N; i++) {
3601            TaskRecord tr = mRecentTasks.get(i);
3602            if (task != tr) {
3603                if (task.userId != tr.userId) {
3604                    continue;
3605                }
3606                if (i > MAX_RECENT_BITMAPS) {
3607                    tr.freeLastThumbnail();
3608                }
3609                final Intent trIntent = tr.intent;
3610                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3611                    (intent == null || !intent.filterEquals(trIntent))) {
3612                    continue;
3613                }
3614                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3615                if (document && trIsDocument) {
3616                    // These are the same document activity (not necessarily the same doc).
3617                    if (maxRecents > 0) {
3618                        --maxRecents;
3619                        continue;
3620                    }
3621                    // Hit the maximum number of documents for this task. Fall through
3622                    // and remove this document from recents.
3623                } else if (document || trIsDocument) {
3624                    // Only one of these is a document. Not the droid we're looking for.
3625                    continue;
3626                }
3627            }
3628
3629            // Either task and tr are the same or, their affinities match or their intents match
3630            // and neither of them is a document, or they are documents using the same activity
3631            // and their maxRecents has been reached.
3632            tr.disposeThumbnail();
3633            mRecentTasks.remove(i);
3634            i--;
3635            N--;
3636            if (task.intent == null) {
3637                // If the new recent task we are adding is not fully
3638                // specified, then replace it with the existing recent task.
3639                task = tr;
3640            }
3641            mTaskPersister.notify(tr, false);
3642        }
3643        if (N >= MAX_RECENT_TASKS) {
3644            mRecentTasks.remove(N-1).disposeThumbnail();
3645        }
3646        mRecentTasks.add(0, task);
3647    }
3648
3649    @Override
3650    public void reportActivityFullyDrawn(IBinder token) {
3651        synchronized (this) {
3652            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3653            if (r == null) {
3654                return;
3655            }
3656            r.reportFullyDrawnLocked();
3657        }
3658    }
3659
3660    @Override
3661    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3662        synchronized (this) {
3663            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3664            if (r == null) {
3665                return;
3666            }
3667            final long origId = Binder.clearCallingIdentity();
3668            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3669            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3670                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3671            if (config != null) {
3672                r.frozenBeforeDestroy = true;
3673                if (!updateConfigurationLocked(config, r, false, false)) {
3674                    mStackSupervisor.resumeTopActivitiesLocked();
3675                }
3676            }
3677            Binder.restoreCallingIdentity(origId);
3678        }
3679    }
3680
3681    @Override
3682    public int getRequestedOrientation(IBinder token) {
3683        synchronized (this) {
3684            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3685            if (r == null) {
3686                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3687            }
3688            return mWindowManager.getAppOrientation(r.appToken);
3689        }
3690    }
3691
3692    /**
3693     * This is the internal entry point for handling Activity.finish().
3694     *
3695     * @param token The Binder token referencing the Activity we want to finish.
3696     * @param resultCode Result code, if any, from this Activity.
3697     * @param resultData Result data (Intent), if any, from this Activity.
3698     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3699     *            the root Activity in the task.
3700     *
3701     * @return Returns true if the activity successfully finished, or false if it is still running.
3702     */
3703    @Override
3704    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3705            boolean finishTask) {
3706        // Refuse possible leaked file descriptors
3707        if (resultData != null && resultData.hasFileDescriptors() == true) {
3708            throw new IllegalArgumentException("File descriptors passed in Intent");
3709        }
3710
3711        synchronized(this) {
3712            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3713            if (r == null) {
3714                return true;
3715            }
3716            // Keep track of the root activity of the task before we finish it
3717            TaskRecord tr = r.task;
3718            ActivityRecord rootR = tr.getRootActivity();
3719            // Do not allow task to finish in Lock Task mode.
3720            if (tr == mStackSupervisor.mLockTaskModeTask) {
3721                if (rootR == r) {
3722                    mStackSupervisor.showLockTaskToast();
3723                    return false;
3724                }
3725            }
3726            if (mController != null) {
3727                // Find the first activity that is not finishing.
3728                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3729                if (next != null) {
3730                    // ask watcher if this is allowed
3731                    boolean resumeOK = true;
3732                    try {
3733                        resumeOK = mController.activityResuming(next.packageName);
3734                    } catch (RemoteException e) {
3735                        mController = null;
3736                        Watchdog.getInstance().setActivityController(null);
3737                    }
3738
3739                    if (!resumeOK) {
3740                        return false;
3741                    }
3742                }
3743            }
3744            final long origId = Binder.clearCallingIdentity();
3745            try {
3746                boolean res;
3747                if (finishTask && r == rootR) {
3748                    // If requested, remove the task that is associated to this activity only if it
3749                    // was the root activity in the task.  The result code and data is ignored because
3750                    // we don't support returning them across task boundaries.
3751                    res = removeTaskByIdLocked(tr.taskId, 0);
3752                } else {
3753                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3754                            resultData, "app-request", true);
3755                }
3756                return res;
3757            } finally {
3758                Binder.restoreCallingIdentity(origId);
3759            }
3760        }
3761    }
3762
3763    @Override
3764    public final void finishHeavyWeightApp() {
3765        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3766                != PackageManager.PERMISSION_GRANTED) {
3767            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3768                    + Binder.getCallingPid()
3769                    + ", uid=" + Binder.getCallingUid()
3770                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3771            Slog.w(TAG, msg);
3772            throw new SecurityException(msg);
3773        }
3774
3775        synchronized(this) {
3776            if (mHeavyWeightProcess == null) {
3777                return;
3778            }
3779
3780            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3781                    mHeavyWeightProcess.activities);
3782            for (int i=0; i<activities.size(); i++) {
3783                ActivityRecord r = activities.get(i);
3784                if (!r.finishing) {
3785                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3786                            null, "finish-heavy", true);
3787                }
3788            }
3789
3790            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3791                    mHeavyWeightProcess.userId, 0));
3792            mHeavyWeightProcess = null;
3793        }
3794    }
3795
3796    @Override
3797    public void crashApplication(int uid, int initialPid, String packageName,
3798            String message) {
3799        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3800                != PackageManager.PERMISSION_GRANTED) {
3801            String msg = "Permission Denial: crashApplication() from pid="
3802                    + Binder.getCallingPid()
3803                    + ", uid=" + Binder.getCallingUid()
3804                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3805            Slog.w(TAG, msg);
3806            throw new SecurityException(msg);
3807        }
3808
3809        synchronized(this) {
3810            ProcessRecord proc = null;
3811
3812            // Figure out which process to kill.  We don't trust that initialPid
3813            // still has any relation to current pids, so must scan through the
3814            // list.
3815            synchronized (mPidsSelfLocked) {
3816                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3817                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3818                    if (p.uid != uid) {
3819                        continue;
3820                    }
3821                    if (p.pid == initialPid) {
3822                        proc = p;
3823                        break;
3824                    }
3825                    if (p.pkgList.containsKey(packageName)) {
3826                        proc = p;
3827                    }
3828                }
3829            }
3830
3831            if (proc == null) {
3832                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3833                        + " initialPid=" + initialPid
3834                        + " packageName=" + packageName);
3835                return;
3836            }
3837
3838            if (proc.thread != null) {
3839                if (proc.pid == Process.myPid()) {
3840                    Log.w(TAG, "crashApplication: trying to crash self!");
3841                    return;
3842                }
3843                long ident = Binder.clearCallingIdentity();
3844                try {
3845                    proc.thread.scheduleCrash(message);
3846                } catch (RemoteException e) {
3847                }
3848                Binder.restoreCallingIdentity(ident);
3849            }
3850        }
3851    }
3852
3853    @Override
3854    public final void finishSubActivity(IBinder token, String resultWho,
3855            int requestCode) {
3856        synchronized(this) {
3857            final long origId = Binder.clearCallingIdentity();
3858            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3859            if (r != null) {
3860                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3861            }
3862            Binder.restoreCallingIdentity(origId);
3863        }
3864    }
3865
3866    @Override
3867    public boolean finishActivityAffinity(IBinder token) {
3868        synchronized(this) {
3869            final long origId = Binder.clearCallingIdentity();
3870            try {
3871                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3872
3873                ActivityRecord rootR = r.task.getRootActivity();
3874                // Do not allow task to finish in Lock Task mode.
3875                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3876                    if (rootR == r) {
3877                        mStackSupervisor.showLockTaskToast();
3878                        return false;
3879                    }
3880                }
3881                boolean res = false;
3882                if (r != null) {
3883                    res = r.task.stack.finishActivityAffinityLocked(r);
3884                }
3885                return res;
3886            } finally {
3887                Binder.restoreCallingIdentity(origId);
3888            }
3889        }
3890    }
3891
3892    @Override
3893    public void finishVoiceTask(IVoiceInteractionSession session) {
3894        synchronized(this) {
3895            final long origId = Binder.clearCallingIdentity();
3896            try {
3897                mStackSupervisor.finishVoiceTask(session);
3898            } finally {
3899                Binder.restoreCallingIdentity(origId);
3900            }
3901        }
3902
3903    }
3904
3905    @Override
3906    public boolean willActivityBeVisible(IBinder token) {
3907        synchronized(this) {
3908            ActivityStack stack = ActivityRecord.getStackLocked(token);
3909            if (stack != null) {
3910                return stack.willActivityBeVisibleLocked(token);
3911            }
3912            return false;
3913        }
3914    }
3915
3916    @Override
3917    public void overridePendingTransition(IBinder token, String packageName,
3918            int enterAnim, int exitAnim) {
3919        synchronized(this) {
3920            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3921            if (self == null) {
3922                return;
3923            }
3924
3925            final long origId = Binder.clearCallingIdentity();
3926
3927            if (self.state == ActivityState.RESUMED
3928                    || self.state == ActivityState.PAUSING) {
3929                mWindowManager.overridePendingAppTransition(packageName,
3930                        enterAnim, exitAnim, null);
3931            }
3932
3933            Binder.restoreCallingIdentity(origId);
3934        }
3935    }
3936
3937    /**
3938     * Main function for removing an existing process from the activity manager
3939     * as a result of that process going away.  Clears out all connections
3940     * to the process.
3941     */
3942    private final void handleAppDiedLocked(ProcessRecord app,
3943            boolean restarting, boolean allowRestart) {
3944        int pid = app.pid;
3945        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3946        if (!restarting) {
3947            removeLruProcessLocked(app);
3948            if (pid > 0) {
3949                ProcessList.remove(pid);
3950            }
3951        }
3952
3953        if (mProfileProc == app) {
3954            clearProfilerLocked();
3955        }
3956
3957        // Remove this application's activities from active lists.
3958        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3959
3960        app.activities.clear();
3961
3962        if (app.instrumentationClass != null) {
3963            Slog.w(TAG, "Crash of app " + app.processName
3964                  + " running instrumentation " + app.instrumentationClass);
3965            Bundle info = new Bundle();
3966            info.putString("shortMsg", "Process crashed.");
3967            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3968        }
3969
3970        if (!restarting) {
3971            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3972                // If there was nothing to resume, and we are not already
3973                // restarting this process, but there is a visible activity that
3974                // is hosted by the process...  then make sure all visible
3975                // activities are running, taking care of restarting this
3976                // process.
3977                if (hasVisibleActivities) {
3978                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3979                }
3980            }
3981        }
3982    }
3983
3984    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3985        IBinder threadBinder = thread.asBinder();
3986        // Find the application record.
3987        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3988            ProcessRecord rec = mLruProcesses.get(i);
3989            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3990                return i;
3991            }
3992        }
3993        return -1;
3994    }
3995
3996    final ProcessRecord getRecordForAppLocked(
3997            IApplicationThread thread) {
3998        if (thread == null) {
3999            return null;
4000        }
4001
4002        int appIndex = getLRURecordIndexForAppLocked(thread);
4003        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4004    }
4005
4006    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4007        // If there are no longer any background processes running,
4008        // and the app that died was not running instrumentation,
4009        // then tell everyone we are now low on memory.
4010        boolean haveBg = false;
4011        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4012            ProcessRecord rec = mLruProcesses.get(i);
4013            if (rec.thread != null
4014                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4015                haveBg = true;
4016                break;
4017            }
4018        }
4019
4020        if (!haveBg) {
4021            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4022            if (doReport) {
4023                long now = SystemClock.uptimeMillis();
4024                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4025                    doReport = false;
4026                } else {
4027                    mLastMemUsageReportTime = now;
4028                }
4029            }
4030            final ArrayList<ProcessMemInfo> memInfos
4031                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4032            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4033            long now = SystemClock.uptimeMillis();
4034            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4035                ProcessRecord rec = mLruProcesses.get(i);
4036                if (rec == dyingProc || rec.thread == null) {
4037                    continue;
4038                }
4039                if (doReport) {
4040                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4041                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4042                }
4043                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4044                    // The low memory report is overriding any current
4045                    // state for a GC request.  Make sure to do
4046                    // heavy/important/visible/foreground processes first.
4047                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4048                        rec.lastRequestedGc = 0;
4049                    } else {
4050                        rec.lastRequestedGc = rec.lastLowMemory;
4051                    }
4052                    rec.reportLowMemory = true;
4053                    rec.lastLowMemory = now;
4054                    mProcessesToGc.remove(rec);
4055                    addProcessToGcListLocked(rec);
4056                }
4057            }
4058            if (doReport) {
4059                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4060                mHandler.sendMessage(msg);
4061            }
4062            scheduleAppGcsLocked();
4063        }
4064    }
4065
4066    final void appDiedLocked(ProcessRecord app, int pid,
4067            IApplicationThread thread) {
4068
4069        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4070        synchronized (stats) {
4071            stats.noteProcessDiedLocked(app.info.uid, pid);
4072        }
4073
4074        Process.killProcessGroup(app.info.uid, pid);
4075
4076        // Clean up already done if the process has been re-started.
4077        if (app.pid == pid && app.thread != null &&
4078                app.thread.asBinder() == thread.asBinder()) {
4079            boolean doLowMem = app.instrumentationClass == null;
4080            boolean doOomAdj = doLowMem;
4081            if (!app.killedByAm) {
4082                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4083                        + ") has died.");
4084                mAllowLowerMemLevel = true;
4085            } else {
4086                // Note that we always want to do oom adj to update our state with the
4087                // new number of procs.
4088                mAllowLowerMemLevel = false;
4089                doLowMem = false;
4090            }
4091            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4092            if (DEBUG_CLEANUP) Slog.v(
4093                TAG, "Dying app: " + app + ", pid: " + pid
4094                + ", thread: " + thread.asBinder());
4095            handleAppDiedLocked(app, false, true);
4096
4097            if (doOomAdj) {
4098                updateOomAdjLocked();
4099            }
4100            if (doLowMem) {
4101                doLowMemReportIfNeededLocked(app);
4102            }
4103        } else if (app.pid != pid) {
4104            // A new process has already been started.
4105            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4106                    + ") has died and restarted (pid " + app.pid + ").");
4107            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4108        } else if (DEBUG_PROCESSES) {
4109            Slog.d(TAG, "Received spurious death notification for thread "
4110                    + thread.asBinder());
4111        }
4112    }
4113
4114    /**
4115     * If a stack trace dump file is configured, dump process stack traces.
4116     * @param clearTraces causes the dump file to be erased prior to the new
4117     *    traces being written, if true; when false, the new traces will be
4118     *    appended to any existing file content.
4119     * @param firstPids of dalvik VM processes to dump stack traces for first
4120     * @param lastPids of dalvik VM processes to dump stack traces for last
4121     * @param nativeProcs optional list of native process names to dump stack crawls
4122     * @return file containing stack traces, or null if no dump file is configured
4123     */
4124    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4125            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4126        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4127        if (tracesPath == null || tracesPath.length() == 0) {
4128            return null;
4129        }
4130
4131        File tracesFile = new File(tracesPath);
4132        try {
4133            File tracesDir = tracesFile.getParentFile();
4134            if (!tracesDir.exists()) {
4135                tracesFile.mkdirs();
4136                if (!SELinux.restorecon(tracesDir)) {
4137                    return null;
4138                }
4139            }
4140            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4141
4142            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4143            tracesFile.createNewFile();
4144            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4145        } catch (IOException e) {
4146            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4147            return null;
4148        }
4149
4150        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4151        return tracesFile;
4152    }
4153
4154    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4155            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4156        // Use a FileObserver to detect when traces finish writing.
4157        // The order of traces is considered important to maintain for legibility.
4158        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4159            @Override
4160            public synchronized void onEvent(int event, String path) { notify(); }
4161        };
4162
4163        try {
4164            observer.startWatching();
4165
4166            // First collect all of the stacks of the most important pids.
4167            if (firstPids != null) {
4168                try {
4169                    int num = firstPids.size();
4170                    for (int i = 0; i < num; i++) {
4171                        synchronized (observer) {
4172                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4173                            observer.wait(200);  // Wait for write-close, give up after 200msec
4174                        }
4175                    }
4176                } catch (InterruptedException e) {
4177                    Log.wtf(TAG, e);
4178                }
4179            }
4180
4181            // Next collect the stacks of the native pids
4182            if (nativeProcs != null) {
4183                int[] pids = Process.getPidsForCommands(nativeProcs);
4184                if (pids != null) {
4185                    for (int pid : pids) {
4186                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4187                    }
4188                }
4189            }
4190
4191            // Lastly, measure CPU usage.
4192            if (processCpuTracker != null) {
4193                processCpuTracker.init();
4194                System.gc();
4195                processCpuTracker.update();
4196                try {
4197                    synchronized (processCpuTracker) {
4198                        processCpuTracker.wait(500); // measure over 1/2 second.
4199                    }
4200                } catch (InterruptedException e) {
4201                }
4202                processCpuTracker.update();
4203
4204                // We'll take the stack crawls of just the top apps using CPU.
4205                final int N = processCpuTracker.countWorkingStats();
4206                int numProcs = 0;
4207                for (int i=0; i<N && numProcs<5; i++) {
4208                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4209                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4210                        numProcs++;
4211                        try {
4212                            synchronized (observer) {
4213                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4214                                observer.wait(200);  // Wait for write-close, give up after 200msec
4215                            }
4216                        } catch (InterruptedException e) {
4217                            Log.wtf(TAG, e);
4218                        }
4219
4220                    }
4221                }
4222            }
4223        } finally {
4224            observer.stopWatching();
4225        }
4226    }
4227
4228    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4229        if (true || IS_USER_BUILD) {
4230            return;
4231        }
4232        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4233        if (tracesPath == null || tracesPath.length() == 0) {
4234            return;
4235        }
4236
4237        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4238        StrictMode.allowThreadDiskWrites();
4239        try {
4240            final File tracesFile = new File(tracesPath);
4241            final File tracesDir = tracesFile.getParentFile();
4242            final File tracesTmp = new File(tracesDir, "__tmp__");
4243            try {
4244                if (!tracesDir.exists()) {
4245                    tracesFile.mkdirs();
4246                    if (!SELinux.restorecon(tracesDir.getPath())) {
4247                        return;
4248                    }
4249                }
4250                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4251
4252                if (tracesFile.exists()) {
4253                    tracesTmp.delete();
4254                    tracesFile.renameTo(tracesTmp);
4255                }
4256                StringBuilder sb = new StringBuilder();
4257                Time tobj = new Time();
4258                tobj.set(System.currentTimeMillis());
4259                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4260                sb.append(": ");
4261                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4262                sb.append(" since ");
4263                sb.append(msg);
4264                FileOutputStream fos = new FileOutputStream(tracesFile);
4265                fos.write(sb.toString().getBytes());
4266                if (app == null) {
4267                    fos.write("\n*** No application process!".getBytes());
4268                }
4269                fos.close();
4270                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4271            } catch (IOException e) {
4272                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4273                return;
4274            }
4275
4276            if (app != null) {
4277                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4278                firstPids.add(app.pid);
4279                dumpStackTraces(tracesPath, firstPids, null, null, null);
4280            }
4281
4282            File lastTracesFile = null;
4283            File curTracesFile = null;
4284            for (int i=9; i>=0; i--) {
4285                String name = String.format(Locale.US, "slow%02d.txt", i);
4286                curTracesFile = new File(tracesDir, name);
4287                if (curTracesFile.exists()) {
4288                    if (lastTracesFile != null) {
4289                        curTracesFile.renameTo(lastTracesFile);
4290                    } else {
4291                        curTracesFile.delete();
4292                    }
4293                }
4294                lastTracesFile = curTracesFile;
4295            }
4296            tracesFile.renameTo(curTracesFile);
4297            if (tracesTmp.exists()) {
4298                tracesTmp.renameTo(tracesFile);
4299            }
4300        } finally {
4301            StrictMode.setThreadPolicy(oldPolicy);
4302        }
4303    }
4304
4305    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4306            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4307        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4308        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4309
4310        if (mController != null) {
4311            try {
4312                // 0 == continue, -1 = kill process immediately
4313                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4314                if (res < 0 && app.pid != MY_PID) {
4315                    Process.killProcess(app.pid);
4316                    Process.killProcessGroup(app.info.uid, app.pid);
4317                }
4318            } catch (RemoteException e) {
4319                mController = null;
4320                Watchdog.getInstance().setActivityController(null);
4321            }
4322        }
4323
4324        long anrTime = SystemClock.uptimeMillis();
4325        if (MONITOR_CPU_USAGE) {
4326            updateCpuStatsNow();
4327        }
4328
4329        synchronized (this) {
4330            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4331            if (mShuttingDown) {
4332                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4333                return;
4334            } else if (app.notResponding) {
4335                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4336                return;
4337            } else if (app.crashing) {
4338                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4339                return;
4340            }
4341
4342            // In case we come through here for the same app before completing
4343            // this one, mark as anring now so we will bail out.
4344            app.notResponding = true;
4345
4346            // Log the ANR to the event log.
4347            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4348                    app.processName, app.info.flags, annotation);
4349
4350            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4351            firstPids.add(app.pid);
4352
4353            int parentPid = app.pid;
4354            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4355            if (parentPid != app.pid) firstPids.add(parentPid);
4356
4357            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4358
4359            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4360                ProcessRecord r = mLruProcesses.get(i);
4361                if (r != null && r.thread != null) {
4362                    int pid = r.pid;
4363                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4364                        if (r.persistent) {
4365                            firstPids.add(pid);
4366                        } else {
4367                            lastPids.put(pid, Boolean.TRUE);
4368                        }
4369                    }
4370                }
4371            }
4372        }
4373
4374        // Log the ANR to the main log.
4375        StringBuilder info = new StringBuilder();
4376        info.setLength(0);
4377        info.append("ANR in ").append(app.processName);
4378        if (activity != null && activity.shortComponentName != null) {
4379            info.append(" (").append(activity.shortComponentName).append(")");
4380        }
4381        info.append("\n");
4382        info.append("PID: ").append(app.pid).append("\n");
4383        if (annotation != null) {
4384            info.append("Reason: ").append(annotation).append("\n");
4385        }
4386        if (parent != null && parent != activity) {
4387            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4388        }
4389
4390        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4391
4392        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4393                NATIVE_STACKS_OF_INTEREST);
4394
4395        String cpuInfo = null;
4396        if (MONITOR_CPU_USAGE) {
4397            updateCpuStatsNow();
4398            synchronized (mProcessCpuThread) {
4399                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4400            }
4401            info.append(processCpuTracker.printCurrentLoad());
4402            info.append(cpuInfo);
4403        }
4404
4405        info.append(processCpuTracker.printCurrentState(anrTime));
4406
4407        Slog.e(TAG, info.toString());
4408        if (tracesFile == null) {
4409            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4410            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4411        }
4412
4413        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4414                cpuInfo, tracesFile, null);
4415
4416        if (mController != null) {
4417            try {
4418                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4419                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4420                if (res != 0) {
4421                    if (res < 0 && app.pid != MY_PID) {
4422                        Process.killProcess(app.pid);
4423                        Process.killProcessGroup(app.info.uid, app.pid);
4424                    } else {
4425                        synchronized (this) {
4426                            mServices.scheduleServiceTimeoutLocked(app);
4427                        }
4428                    }
4429                    return;
4430                }
4431            } catch (RemoteException e) {
4432                mController = null;
4433                Watchdog.getInstance().setActivityController(null);
4434            }
4435        }
4436
4437        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4438        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4439                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4440
4441        synchronized (this) {
4442            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4443                killUnneededProcessLocked(app, "background ANR");
4444                return;
4445            }
4446
4447            // Set the app's notResponding state, and look up the errorReportReceiver
4448            makeAppNotRespondingLocked(app,
4449                    activity != null ? activity.shortComponentName : null,
4450                    annotation != null ? "ANR " + annotation : "ANR",
4451                    info.toString());
4452
4453            // Bring up the infamous App Not Responding dialog
4454            Message msg = Message.obtain();
4455            HashMap<String, Object> map = new HashMap<String, Object>();
4456            msg.what = SHOW_NOT_RESPONDING_MSG;
4457            msg.obj = map;
4458            msg.arg1 = aboveSystem ? 1 : 0;
4459            map.put("app", app);
4460            if (activity != null) {
4461                map.put("activity", activity);
4462            }
4463
4464            mHandler.sendMessage(msg);
4465        }
4466    }
4467
4468    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4469        if (!mLaunchWarningShown) {
4470            mLaunchWarningShown = true;
4471            mHandler.post(new Runnable() {
4472                @Override
4473                public void run() {
4474                    synchronized (ActivityManagerService.this) {
4475                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4476                        d.show();
4477                        mHandler.postDelayed(new Runnable() {
4478                            @Override
4479                            public void run() {
4480                                synchronized (ActivityManagerService.this) {
4481                                    d.dismiss();
4482                                    mLaunchWarningShown = false;
4483                                }
4484                            }
4485                        }, 4000);
4486                    }
4487                }
4488            });
4489        }
4490    }
4491
4492    @Override
4493    public boolean clearApplicationUserData(final String packageName,
4494            final IPackageDataObserver observer, int userId) {
4495        enforceNotIsolatedCaller("clearApplicationUserData");
4496        int uid = Binder.getCallingUid();
4497        int pid = Binder.getCallingPid();
4498        userId = handleIncomingUser(pid, uid,
4499                userId, false, true, "clearApplicationUserData", null);
4500        long callingId = Binder.clearCallingIdentity();
4501        try {
4502            IPackageManager pm = AppGlobals.getPackageManager();
4503            int pkgUid = -1;
4504            synchronized(this) {
4505                try {
4506                    pkgUid = pm.getPackageUid(packageName, userId);
4507                } catch (RemoteException e) {
4508                }
4509                if (pkgUid == -1) {
4510                    Slog.w(TAG, "Invalid packageName: " + packageName);
4511                    if (observer != null) {
4512                        try {
4513                            observer.onRemoveCompleted(packageName, false);
4514                        } catch (RemoteException e) {
4515                            Slog.i(TAG, "Observer no longer exists.");
4516                        }
4517                    }
4518                    return false;
4519                }
4520                if (uid == pkgUid || checkComponentPermission(
4521                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4522                        pid, uid, -1, true)
4523                        == PackageManager.PERMISSION_GRANTED) {
4524                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4525                } else {
4526                    throw new SecurityException("PID " + pid + " does not have permission "
4527                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4528                                    + " of package " + packageName);
4529                }
4530            }
4531
4532            try {
4533                // Clear application user data
4534                pm.clearApplicationUserData(packageName, observer, userId);
4535
4536                // Remove all permissions granted from/to this package
4537                removeUriPermissionsForPackageLocked(packageName, userId, true);
4538
4539                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4540                        Uri.fromParts("package", packageName, null));
4541                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4542                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4543                        null, null, 0, null, null, null, false, false, userId);
4544            } catch (RemoteException e) {
4545            }
4546        } finally {
4547            Binder.restoreCallingIdentity(callingId);
4548        }
4549        return true;
4550    }
4551
4552    @Override
4553    public void killBackgroundProcesses(final String packageName, int userId) {
4554        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4555                != PackageManager.PERMISSION_GRANTED &&
4556                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4557                        != PackageManager.PERMISSION_GRANTED) {
4558            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4559                    + Binder.getCallingPid()
4560                    + ", uid=" + Binder.getCallingUid()
4561                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4562            Slog.w(TAG, msg);
4563            throw new SecurityException(msg);
4564        }
4565
4566        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4567                userId, true, true, "killBackgroundProcesses", null);
4568        long callingId = Binder.clearCallingIdentity();
4569        try {
4570            IPackageManager pm = AppGlobals.getPackageManager();
4571            synchronized(this) {
4572                int appId = -1;
4573                try {
4574                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4575                } catch (RemoteException e) {
4576                }
4577                if (appId == -1) {
4578                    Slog.w(TAG, "Invalid packageName: " + packageName);
4579                    return;
4580                }
4581                killPackageProcessesLocked(packageName, appId, userId,
4582                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4583            }
4584        } finally {
4585            Binder.restoreCallingIdentity(callingId);
4586        }
4587    }
4588
4589    @Override
4590    public void killAllBackgroundProcesses() {
4591        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4592                != PackageManager.PERMISSION_GRANTED) {
4593            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4594                    + Binder.getCallingPid()
4595                    + ", uid=" + Binder.getCallingUid()
4596                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4597            Slog.w(TAG, msg);
4598            throw new SecurityException(msg);
4599        }
4600
4601        long callingId = Binder.clearCallingIdentity();
4602        try {
4603            synchronized(this) {
4604                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4605                final int NP = mProcessNames.getMap().size();
4606                for (int ip=0; ip<NP; ip++) {
4607                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4608                    final int NA = apps.size();
4609                    for (int ia=0; ia<NA; ia++) {
4610                        ProcessRecord app = apps.valueAt(ia);
4611                        if (app.persistent) {
4612                            // we don't kill persistent processes
4613                            continue;
4614                        }
4615                        if (app.removed) {
4616                            procs.add(app);
4617                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4618                            app.removed = true;
4619                            procs.add(app);
4620                        }
4621                    }
4622                }
4623
4624                int N = procs.size();
4625                for (int i=0; i<N; i++) {
4626                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4627                }
4628                mAllowLowerMemLevel = true;
4629                updateOomAdjLocked();
4630                doLowMemReportIfNeededLocked(null);
4631            }
4632        } finally {
4633            Binder.restoreCallingIdentity(callingId);
4634        }
4635    }
4636
4637    @Override
4638    public void forceStopPackage(final String packageName, int userId) {
4639        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4640                != PackageManager.PERMISSION_GRANTED) {
4641            String msg = "Permission Denial: forceStopPackage() from pid="
4642                    + Binder.getCallingPid()
4643                    + ", uid=" + Binder.getCallingUid()
4644                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4645            Slog.w(TAG, msg);
4646            throw new SecurityException(msg);
4647        }
4648        final int callingPid = Binder.getCallingPid();
4649        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4650                userId, true, true, "forceStopPackage", null);
4651        long callingId = Binder.clearCallingIdentity();
4652        try {
4653            IPackageManager pm = AppGlobals.getPackageManager();
4654            synchronized(this) {
4655                int[] users = userId == UserHandle.USER_ALL
4656                        ? getUsersLocked() : new int[] { userId };
4657                for (int user : users) {
4658                    int pkgUid = -1;
4659                    try {
4660                        pkgUid = pm.getPackageUid(packageName, user);
4661                    } catch (RemoteException e) {
4662                    }
4663                    if (pkgUid == -1) {
4664                        Slog.w(TAG, "Invalid packageName: " + packageName);
4665                        continue;
4666                    }
4667                    try {
4668                        pm.setPackageStoppedState(packageName, true, user);
4669                    } catch (RemoteException e) {
4670                    } catch (IllegalArgumentException e) {
4671                        Slog.w(TAG, "Failed trying to unstop package "
4672                                + packageName + ": " + e);
4673                    }
4674                    if (isUserRunningLocked(user, false)) {
4675                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4676                    }
4677                }
4678            }
4679        } finally {
4680            Binder.restoreCallingIdentity(callingId);
4681        }
4682    }
4683
4684    /*
4685     * The pkg name and app id have to be specified.
4686     */
4687    @Override
4688    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4689        if (pkg == null) {
4690            return;
4691        }
4692        // Make sure the uid is valid.
4693        if (appid < 0) {
4694            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4695            return;
4696        }
4697        int callerUid = Binder.getCallingUid();
4698        // Only the system server can kill an application
4699        if (callerUid == Process.SYSTEM_UID) {
4700            // Post an aysnc message to kill the application
4701            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4702            msg.arg1 = appid;
4703            msg.arg2 = 0;
4704            Bundle bundle = new Bundle();
4705            bundle.putString("pkg", pkg);
4706            bundle.putString("reason", reason);
4707            msg.obj = bundle;
4708            mHandler.sendMessage(msg);
4709        } else {
4710            throw new SecurityException(callerUid + " cannot kill pkg: " +
4711                    pkg);
4712        }
4713    }
4714
4715    @Override
4716    public void closeSystemDialogs(String reason) {
4717        enforceNotIsolatedCaller("closeSystemDialogs");
4718
4719        final int pid = Binder.getCallingPid();
4720        final int uid = Binder.getCallingUid();
4721        final long origId = Binder.clearCallingIdentity();
4722        try {
4723            synchronized (this) {
4724                // Only allow this from foreground processes, so that background
4725                // applications can't abuse it to prevent system UI from being shown.
4726                if (uid >= Process.FIRST_APPLICATION_UID) {
4727                    ProcessRecord proc;
4728                    synchronized (mPidsSelfLocked) {
4729                        proc = mPidsSelfLocked.get(pid);
4730                    }
4731                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4732                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4733                                + " from background process " + proc);
4734                        return;
4735                    }
4736                }
4737                closeSystemDialogsLocked(reason);
4738            }
4739        } finally {
4740            Binder.restoreCallingIdentity(origId);
4741        }
4742    }
4743
4744    void closeSystemDialogsLocked(String reason) {
4745        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4746        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4747                | Intent.FLAG_RECEIVER_FOREGROUND);
4748        if (reason != null) {
4749            intent.putExtra("reason", reason);
4750        }
4751        mWindowManager.closeSystemDialogs(reason);
4752
4753        mStackSupervisor.closeSystemDialogsLocked();
4754
4755        broadcastIntentLocked(null, null, intent, null,
4756                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4757                Process.SYSTEM_UID, UserHandle.USER_ALL);
4758    }
4759
4760    @Override
4761    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4762        enforceNotIsolatedCaller("getProcessMemoryInfo");
4763        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4764        for (int i=pids.length-1; i>=0; i--) {
4765            ProcessRecord proc;
4766            int oomAdj;
4767            synchronized (this) {
4768                synchronized (mPidsSelfLocked) {
4769                    proc = mPidsSelfLocked.get(pids[i]);
4770                    oomAdj = proc != null ? proc.setAdj : 0;
4771                }
4772            }
4773            infos[i] = new Debug.MemoryInfo();
4774            Debug.getMemoryInfo(pids[i], infos[i]);
4775            if (proc != null) {
4776                synchronized (this) {
4777                    if (proc.thread != null && proc.setAdj == oomAdj) {
4778                        // Record this for posterity if the process has been stable.
4779                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4780                                infos[i].getTotalUss(), false, proc.pkgList);
4781                    }
4782                }
4783            }
4784        }
4785        return infos;
4786    }
4787
4788    @Override
4789    public long[] getProcessPss(int[] pids) {
4790        enforceNotIsolatedCaller("getProcessPss");
4791        long[] pss = new long[pids.length];
4792        for (int i=pids.length-1; i>=0; i--) {
4793            ProcessRecord proc;
4794            int oomAdj;
4795            synchronized (this) {
4796                synchronized (mPidsSelfLocked) {
4797                    proc = mPidsSelfLocked.get(pids[i]);
4798                    oomAdj = proc != null ? proc.setAdj : 0;
4799                }
4800            }
4801            long[] tmpUss = new long[1];
4802            pss[i] = Debug.getPss(pids[i], tmpUss);
4803            if (proc != null) {
4804                synchronized (this) {
4805                    if (proc.thread != null && proc.setAdj == oomAdj) {
4806                        // Record this for posterity if the process has been stable.
4807                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4808                    }
4809                }
4810            }
4811        }
4812        return pss;
4813    }
4814
4815    @Override
4816    public void killApplicationProcess(String processName, int uid) {
4817        if (processName == null) {
4818            return;
4819        }
4820
4821        int callerUid = Binder.getCallingUid();
4822        // Only the system server can kill an application
4823        if (callerUid == Process.SYSTEM_UID) {
4824            synchronized (this) {
4825                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4826                if (app != null && app.thread != null) {
4827                    try {
4828                        app.thread.scheduleSuicide();
4829                    } catch (RemoteException e) {
4830                        // If the other end already died, then our work here is done.
4831                    }
4832                } else {
4833                    Slog.w(TAG, "Process/uid not found attempting kill of "
4834                            + processName + " / " + uid);
4835                }
4836            }
4837        } else {
4838            throw new SecurityException(callerUid + " cannot kill app process: " +
4839                    processName);
4840        }
4841    }
4842
4843    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4844        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4845                false, true, false, false, UserHandle.getUserId(uid), reason);
4846        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4847                Uri.fromParts("package", packageName, null));
4848        if (!mProcessesReady) {
4849            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4850                    | Intent.FLAG_RECEIVER_FOREGROUND);
4851        }
4852        intent.putExtra(Intent.EXTRA_UID, uid);
4853        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4854        broadcastIntentLocked(null, null, intent,
4855                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4856                false, false,
4857                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4858    }
4859
4860    private void forceStopUserLocked(int userId, String reason) {
4861        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4862        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4863        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4864                | Intent.FLAG_RECEIVER_FOREGROUND);
4865        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4866        broadcastIntentLocked(null, null, intent,
4867                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4868                false, false,
4869                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4870    }
4871
4872    private final boolean killPackageProcessesLocked(String packageName, int appId,
4873            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4874            boolean doit, boolean evenPersistent, String reason) {
4875        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4876
4877        // Remove all processes this package may have touched: all with the
4878        // same UID (except for the system or root user), and all whose name
4879        // matches the package name.
4880        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4881        final int NP = mProcessNames.getMap().size();
4882        for (int ip=0; ip<NP; ip++) {
4883            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4884            final int NA = apps.size();
4885            for (int ia=0; ia<NA; ia++) {
4886                ProcessRecord app = apps.valueAt(ia);
4887                if (app.persistent && !evenPersistent) {
4888                    // we don't kill persistent processes
4889                    continue;
4890                }
4891                if (app.removed) {
4892                    if (doit) {
4893                        procs.add(app);
4894                    }
4895                    continue;
4896                }
4897
4898                // Skip process if it doesn't meet our oom adj requirement.
4899                if (app.setAdj < minOomAdj) {
4900                    continue;
4901                }
4902
4903                // If no package is specified, we call all processes under the
4904                // give user id.
4905                if (packageName == null) {
4906                    if (app.userId != userId) {
4907                        continue;
4908                    }
4909                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4910                        continue;
4911                    }
4912                // Package has been specified, we want to hit all processes
4913                // that match it.  We need to qualify this by the processes
4914                // that are running under the specified app and user ID.
4915                } else {
4916                    if (UserHandle.getAppId(app.uid) != appId) {
4917                        continue;
4918                    }
4919                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4920                        continue;
4921                    }
4922                    if (!app.pkgList.containsKey(packageName)) {
4923                        continue;
4924                    }
4925                }
4926
4927                // Process has passed all conditions, kill it!
4928                if (!doit) {
4929                    return true;
4930                }
4931                app.removed = true;
4932                procs.add(app);
4933            }
4934        }
4935
4936        int N = procs.size();
4937        for (int i=0; i<N; i++) {
4938            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4939        }
4940        updateOomAdjLocked();
4941        return N > 0;
4942    }
4943
4944    private final boolean forceStopPackageLocked(String name, int appId,
4945            boolean callerWillRestart, boolean purgeCache, boolean doit,
4946            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4947        int i;
4948        int N;
4949
4950        if (userId == UserHandle.USER_ALL && name == null) {
4951            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4952        }
4953
4954        if (appId < 0 && name != null) {
4955            try {
4956                appId = UserHandle.getAppId(
4957                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4958            } catch (RemoteException e) {
4959            }
4960        }
4961
4962        if (doit) {
4963            if (name != null) {
4964                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4965                        + " user=" + userId + ": " + reason);
4966            } else {
4967                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4968            }
4969
4970            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4971            for (int ip=pmap.size()-1; ip>=0; ip--) {
4972                SparseArray<Long> ba = pmap.valueAt(ip);
4973                for (i=ba.size()-1; i>=0; i--) {
4974                    boolean remove = false;
4975                    final int entUid = ba.keyAt(i);
4976                    if (name != null) {
4977                        if (userId == UserHandle.USER_ALL) {
4978                            if (UserHandle.getAppId(entUid) == appId) {
4979                                remove = true;
4980                            }
4981                        } else {
4982                            if (entUid == UserHandle.getUid(userId, appId)) {
4983                                remove = true;
4984                            }
4985                        }
4986                    } else if (UserHandle.getUserId(entUid) == userId) {
4987                        remove = true;
4988                    }
4989                    if (remove) {
4990                        ba.removeAt(i);
4991                    }
4992                }
4993                if (ba.size() == 0) {
4994                    pmap.removeAt(ip);
4995                }
4996            }
4997        }
4998
4999        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5000                -100, callerWillRestart, true, doit, evenPersistent,
5001                name == null ? ("stop user " + userId) : ("stop " + name));
5002
5003        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5004            if (!doit) {
5005                return true;
5006            }
5007            didSomething = true;
5008        }
5009
5010        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5011            if (!doit) {
5012                return true;
5013            }
5014            didSomething = true;
5015        }
5016
5017        if (name == null) {
5018            // Remove all sticky broadcasts from this user.
5019            mStickyBroadcasts.remove(userId);
5020        }
5021
5022        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5023        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5024                userId, providers)) {
5025            if (!doit) {
5026                return true;
5027            }
5028            didSomething = true;
5029        }
5030        N = providers.size();
5031        for (i=0; i<N; i++) {
5032            removeDyingProviderLocked(null, providers.get(i), true);
5033        }
5034
5035        // Remove transient permissions granted from/to this package/user
5036        removeUriPermissionsForPackageLocked(name, userId, false);
5037
5038        if (name == null || uninstalling) {
5039            // Remove pending intents.  For now we only do this when force
5040            // stopping users, because we have some problems when doing this
5041            // for packages -- app widgets are not currently cleaned up for
5042            // such packages, so they can be left with bad pending intents.
5043            if (mIntentSenderRecords.size() > 0) {
5044                Iterator<WeakReference<PendingIntentRecord>> it
5045                        = mIntentSenderRecords.values().iterator();
5046                while (it.hasNext()) {
5047                    WeakReference<PendingIntentRecord> wpir = it.next();
5048                    if (wpir == null) {
5049                        it.remove();
5050                        continue;
5051                    }
5052                    PendingIntentRecord pir = wpir.get();
5053                    if (pir == null) {
5054                        it.remove();
5055                        continue;
5056                    }
5057                    if (name == null) {
5058                        // Stopping user, remove all objects for the user.
5059                        if (pir.key.userId != userId) {
5060                            // Not the same user, skip it.
5061                            continue;
5062                        }
5063                    } else {
5064                        if (UserHandle.getAppId(pir.uid) != appId) {
5065                            // Different app id, skip it.
5066                            continue;
5067                        }
5068                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5069                            // Different user, skip it.
5070                            continue;
5071                        }
5072                        if (!pir.key.packageName.equals(name)) {
5073                            // Different package, skip it.
5074                            continue;
5075                        }
5076                    }
5077                    if (!doit) {
5078                        return true;
5079                    }
5080                    didSomething = true;
5081                    it.remove();
5082                    pir.canceled = true;
5083                    if (pir.key.activity != null) {
5084                        pir.key.activity.pendingResults.remove(pir.ref);
5085                    }
5086                }
5087            }
5088        }
5089
5090        if (doit) {
5091            if (purgeCache && name != null) {
5092                AttributeCache ac = AttributeCache.instance();
5093                if (ac != null) {
5094                    ac.removePackage(name);
5095                }
5096            }
5097            if (mBooted) {
5098                mStackSupervisor.resumeTopActivitiesLocked();
5099                mStackSupervisor.scheduleIdleLocked();
5100            }
5101        }
5102
5103        return didSomething;
5104    }
5105
5106    private final boolean removeProcessLocked(ProcessRecord app,
5107            boolean callerWillRestart, boolean allowRestart, String reason) {
5108        final String name = app.processName;
5109        final int uid = app.uid;
5110        if (DEBUG_PROCESSES) Slog.d(
5111            TAG, "Force removing proc " + app.toShortString() + " (" + name
5112            + "/" + uid + ")");
5113
5114        mProcessNames.remove(name, uid);
5115        mIsolatedProcesses.remove(app.uid);
5116        if (mHeavyWeightProcess == app) {
5117            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5118                    mHeavyWeightProcess.userId, 0));
5119            mHeavyWeightProcess = null;
5120        }
5121        boolean needRestart = false;
5122        if (app.pid > 0 && app.pid != MY_PID) {
5123            int pid = app.pid;
5124            synchronized (mPidsSelfLocked) {
5125                mPidsSelfLocked.remove(pid);
5126                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5127            }
5128            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5129            if (app.isolated) {
5130                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5131            }
5132            killUnneededProcessLocked(app, reason);
5133            Process.killProcessGroup(app.info.uid, app.pid);
5134            handleAppDiedLocked(app, true, allowRestart);
5135            removeLruProcessLocked(app);
5136
5137            if (app.persistent && !app.isolated) {
5138                if (!callerWillRestart) {
5139                    addAppLocked(app.info, false, null /* ABI override */);
5140                } else {
5141                    needRestart = true;
5142                }
5143            }
5144        } else {
5145            mRemovedProcesses.add(app);
5146        }
5147
5148        return needRestart;
5149    }
5150
5151    private final void processStartTimedOutLocked(ProcessRecord app) {
5152        final int pid = app.pid;
5153        boolean gone = false;
5154        synchronized (mPidsSelfLocked) {
5155            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5156            if (knownApp != null && knownApp.thread == null) {
5157                mPidsSelfLocked.remove(pid);
5158                gone = true;
5159            }
5160        }
5161
5162        if (gone) {
5163            Slog.w(TAG, "Process " + app + " failed to attach");
5164            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5165                    pid, app.uid, app.processName);
5166            mProcessNames.remove(app.processName, app.uid);
5167            mIsolatedProcesses.remove(app.uid);
5168            if (mHeavyWeightProcess == app) {
5169                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5170                        mHeavyWeightProcess.userId, 0));
5171                mHeavyWeightProcess = null;
5172            }
5173            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5174            if (app.isolated) {
5175                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5176            }
5177            // Take care of any launching providers waiting for this process.
5178            checkAppInLaunchingProvidersLocked(app, true);
5179            // Take care of any services that are waiting for the process.
5180            mServices.processStartTimedOutLocked(app);
5181            killUnneededProcessLocked(app, "start timeout");
5182            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5183                Slog.w(TAG, "Unattached app died before backup, skipping");
5184                try {
5185                    IBackupManager bm = IBackupManager.Stub.asInterface(
5186                            ServiceManager.getService(Context.BACKUP_SERVICE));
5187                    bm.agentDisconnected(app.info.packageName);
5188                } catch (RemoteException e) {
5189                    // Can't happen; the backup manager is local
5190                }
5191            }
5192            if (isPendingBroadcastProcessLocked(pid)) {
5193                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5194                skipPendingBroadcastLocked(pid);
5195            }
5196        } else {
5197            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5198        }
5199    }
5200
5201    private final boolean attachApplicationLocked(IApplicationThread thread,
5202            int pid) {
5203
5204        // Find the application record that is being attached...  either via
5205        // the pid if we are running in multiple processes, or just pull the
5206        // next app record if we are emulating process with anonymous threads.
5207        ProcessRecord app;
5208        if (pid != MY_PID && pid >= 0) {
5209            synchronized (mPidsSelfLocked) {
5210                app = mPidsSelfLocked.get(pid);
5211            }
5212        } else {
5213            app = null;
5214        }
5215
5216        if (app == null) {
5217            Slog.w(TAG, "No pending application record for pid " + pid
5218                    + " (IApplicationThread " + thread + "); dropping process");
5219            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5220            if (pid > 0 && pid != MY_PID) {
5221                Process.killProcessQuiet(pid);
5222                //TODO: Process.killProcessGroup(app.info.uid, pid);
5223            } else {
5224                try {
5225                    thread.scheduleExit();
5226                } catch (Exception e) {
5227                    // Ignore exceptions.
5228                }
5229            }
5230            return false;
5231        }
5232
5233        // If this application record is still attached to a previous
5234        // process, clean it up now.
5235        if (app.thread != null) {
5236            handleAppDiedLocked(app, true, true);
5237        }
5238
5239        // Tell the process all about itself.
5240
5241        if (localLOGV) Slog.v(
5242                TAG, "Binding process pid " + pid + " to record " + app);
5243
5244        final String processName = app.processName;
5245        try {
5246            AppDeathRecipient adr = new AppDeathRecipient(
5247                    app, pid, thread);
5248            thread.asBinder().linkToDeath(adr, 0);
5249            app.deathRecipient = adr;
5250        } catch (RemoteException e) {
5251            app.resetPackageList(mProcessStats);
5252            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5253            return false;
5254        }
5255
5256        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5257
5258        app.makeActive(thread, mProcessStats);
5259        app.curAdj = app.setAdj = -100;
5260        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5261        app.forcingToForeground = null;
5262        updateProcessForegroundLocked(app, false, false);
5263        app.hasShownUi = false;
5264        app.debugging = false;
5265        app.cached = false;
5266
5267        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5268
5269        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5270        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5271
5272        if (!normalMode) {
5273            Slog.i(TAG, "Launching preboot mode app: " + app);
5274        }
5275
5276        if (localLOGV) Slog.v(
5277            TAG, "New app record " + app
5278            + " thread=" + thread.asBinder() + " pid=" + pid);
5279        try {
5280            int testMode = IApplicationThread.DEBUG_OFF;
5281            if (mDebugApp != null && mDebugApp.equals(processName)) {
5282                testMode = mWaitForDebugger
5283                    ? IApplicationThread.DEBUG_WAIT
5284                    : IApplicationThread.DEBUG_ON;
5285                app.debugging = true;
5286                if (mDebugTransient) {
5287                    mDebugApp = mOrigDebugApp;
5288                    mWaitForDebugger = mOrigWaitForDebugger;
5289                }
5290            }
5291            String profileFile = app.instrumentationProfileFile;
5292            ParcelFileDescriptor profileFd = null;
5293            boolean profileAutoStop = false;
5294            if (mProfileApp != null && mProfileApp.equals(processName)) {
5295                mProfileProc = app;
5296                profileFile = mProfileFile;
5297                profileFd = mProfileFd;
5298                profileAutoStop = mAutoStopProfiler;
5299            }
5300            boolean enableOpenGlTrace = false;
5301            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5302                enableOpenGlTrace = true;
5303                mOpenGlTraceApp = null;
5304            }
5305
5306            // If the app is being launched for restore or full backup, set it up specially
5307            boolean isRestrictedBackupMode = false;
5308            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5309                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5310                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5311                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5312            }
5313
5314            ensurePackageDexOpt(app.instrumentationInfo != null
5315                    ? app.instrumentationInfo.packageName
5316                    : app.info.packageName);
5317            if (app.instrumentationClass != null) {
5318                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5319            }
5320            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5321                    + processName + " with config " + mConfiguration);
5322            ApplicationInfo appInfo = app.instrumentationInfo != null
5323                    ? app.instrumentationInfo : app.info;
5324            app.compat = compatibilityInfoForPackageLocked(appInfo);
5325            if (profileFd != null) {
5326                profileFd = profileFd.dup();
5327            }
5328            thread.bindApplication(processName, appInfo, providers,
5329                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5330                    app.instrumentationArguments, app.instrumentationWatcher,
5331                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5332                    isRestrictedBackupMode || !normalMode, app.persistent,
5333                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5334                    mCoreSettingsObserver.getCoreSettingsLocked());
5335            updateLruProcessLocked(app, false, null);
5336            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5337        } catch (Exception e) {
5338            // todo: Yikes!  What should we do?  For now we will try to
5339            // start another process, but that could easily get us in
5340            // an infinite loop of restarting processes...
5341            Slog.w(TAG, "Exception thrown during bind!", e);
5342
5343            app.resetPackageList(mProcessStats);
5344            app.unlinkDeathRecipient();
5345            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5346            return false;
5347        }
5348
5349        // Remove this record from the list of starting applications.
5350        mPersistentStartingProcesses.remove(app);
5351        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5352                "Attach application locked removing on hold: " + app);
5353        mProcessesOnHold.remove(app);
5354
5355        boolean badApp = false;
5356        boolean didSomething = false;
5357
5358        // See if the top visible activity is waiting to run in this process...
5359        if (normalMode) {
5360            try {
5361                if (mStackSupervisor.attachApplicationLocked(app)) {
5362                    didSomething = true;
5363                }
5364            } catch (Exception e) {
5365                badApp = true;
5366            }
5367        }
5368
5369        // Find any services that should be running in this process...
5370        if (!badApp) {
5371            try {
5372                didSomething |= mServices.attachApplicationLocked(app, processName);
5373            } catch (Exception e) {
5374                badApp = true;
5375            }
5376        }
5377
5378        // Check if a next-broadcast receiver is in this process...
5379        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5380            try {
5381                didSomething |= sendPendingBroadcastsLocked(app);
5382            } catch (Exception e) {
5383                // If the app died trying to launch the receiver we declare it 'bad'
5384                badApp = true;
5385            }
5386        }
5387
5388        // Check whether the next backup agent is in this process...
5389        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5390            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5391            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5392            try {
5393                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5394                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5395                        mBackupTarget.backupMode);
5396            } catch (Exception e) {
5397                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5398                e.printStackTrace();
5399            }
5400        }
5401
5402        if (badApp) {
5403            // todo: Also need to kill application to deal with all
5404            // kinds of exceptions.
5405            handleAppDiedLocked(app, false, true);
5406            return false;
5407        }
5408
5409        if (!didSomething) {
5410            updateOomAdjLocked();
5411        }
5412
5413        return true;
5414    }
5415
5416    @Override
5417    public final void attachApplication(IApplicationThread thread) {
5418        synchronized (this) {
5419            int callingPid = Binder.getCallingPid();
5420            final long origId = Binder.clearCallingIdentity();
5421            attachApplicationLocked(thread, callingPid);
5422            Binder.restoreCallingIdentity(origId);
5423        }
5424    }
5425
5426    @Override
5427    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5428        final long origId = Binder.clearCallingIdentity();
5429        synchronized (this) {
5430            ActivityStack stack = ActivityRecord.getStackLocked(token);
5431            if (stack != null) {
5432                ActivityRecord r =
5433                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5434                if (stopProfiling) {
5435                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5436                        try {
5437                            mProfileFd.close();
5438                        } catch (IOException e) {
5439                        }
5440                        clearProfilerLocked();
5441                    }
5442                }
5443            }
5444        }
5445        Binder.restoreCallingIdentity(origId);
5446    }
5447
5448    void enableScreenAfterBoot() {
5449        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5450                SystemClock.uptimeMillis());
5451        mWindowManager.enableScreenAfterBoot();
5452
5453        synchronized (this) {
5454            updateEventDispatchingLocked();
5455        }
5456    }
5457
5458    @Override
5459    public void showBootMessage(final CharSequence msg, final boolean always) {
5460        enforceNotIsolatedCaller("showBootMessage");
5461        mWindowManager.showBootMessage(msg, always);
5462    }
5463
5464    @Override
5465    public void dismissKeyguardOnNextActivity() {
5466        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5467        final long token = Binder.clearCallingIdentity();
5468        try {
5469            synchronized (this) {
5470                if (DEBUG_LOCKSCREEN) logLockScreen("");
5471                if (mLockScreenShown) {
5472                    mLockScreenShown = false;
5473                    comeOutOfSleepIfNeededLocked();
5474                }
5475                mStackSupervisor.setDismissKeyguard(true);
5476            }
5477        } finally {
5478            Binder.restoreCallingIdentity(token);
5479        }
5480    }
5481
5482    final void finishBooting() {
5483        // Register receivers to handle package update events
5484        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5485
5486        synchronized (this) {
5487            // Ensure that any processes we had put on hold are now started
5488            // up.
5489            final int NP = mProcessesOnHold.size();
5490            if (NP > 0) {
5491                ArrayList<ProcessRecord> procs =
5492                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5493                for (int ip=0; ip<NP; ip++) {
5494                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5495                            + procs.get(ip));
5496                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5497                }
5498            }
5499
5500            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5501                // Start looking for apps that are abusing wake locks.
5502                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5503                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5504                // Tell anyone interested that we are done booting!
5505                SystemProperties.set("sys.boot_completed", "1");
5506                SystemProperties.set("dev.bootcomplete", "1");
5507                for (int i=0; i<mStartedUsers.size(); i++) {
5508                    UserStartedState uss = mStartedUsers.valueAt(i);
5509                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5510                        uss.mState = UserStartedState.STATE_RUNNING;
5511                        final int userId = mStartedUsers.keyAt(i);
5512                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5513                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5514                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5515                        broadcastIntentLocked(null, null, intent, null,
5516                                new IIntentReceiver.Stub() {
5517                                    @Override
5518                                    public void performReceive(Intent intent, int resultCode,
5519                                            String data, Bundle extras, boolean ordered,
5520                                            boolean sticky, int sendingUser) {
5521                                        synchronized (ActivityManagerService.this) {
5522                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5523                                                    true, false);
5524                                        }
5525                                    }
5526                                },
5527                                0, null, null,
5528                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5529                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5530                                userId);
5531                    }
5532                }
5533                scheduleStartProfilesLocked();
5534            }
5535        }
5536    }
5537
5538    final void ensureBootCompleted() {
5539        boolean booting;
5540        boolean enableScreen;
5541        synchronized (this) {
5542            booting = mBooting;
5543            mBooting = false;
5544            enableScreen = !mBooted;
5545            mBooted = true;
5546        }
5547
5548        if (booting) {
5549            finishBooting();
5550        }
5551
5552        if (enableScreen) {
5553            enableScreenAfterBoot();
5554        }
5555    }
5556
5557    @Override
5558    public final void activityResumed(IBinder token) {
5559        final long origId = Binder.clearCallingIdentity();
5560        synchronized(this) {
5561            ActivityStack stack = ActivityRecord.getStackLocked(token);
5562            if (stack != null) {
5563                ActivityRecord.activityResumedLocked(token);
5564            }
5565        }
5566        Binder.restoreCallingIdentity(origId);
5567    }
5568
5569    @Override
5570    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5571        final long origId = Binder.clearCallingIdentity();
5572        synchronized(this) {
5573            ActivityStack stack = ActivityRecord.getStackLocked(token);
5574            if (stack != null) {
5575                stack.activityPausedLocked(token, false, persistentState);
5576            }
5577        }
5578        Binder.restoreCallingIdentity(origId);
5579    }
5580
5581    @Override
5582    public final void activityStopped(IBinder token, Bundle icicle,
5583            PersistableBundle persistentState, CharSequence description) {
5584        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5585
5586        // Refuse possible leaked file descriptors
5587        if (icicle != null && icicle.hasFileDescriptors()) {
5588            throw new IllegalArgumentException("File descriptors passed in Bundle");
5589        }
5590
5591        final long origId = Binder.clearCallingIdentity();
5592
5593        synchronized (this) {
5594            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5595            if (r != null) {
5596                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5597            }
5598        }
5599
5600        trimApplications();
5601
5602        Binder.restoreCallingIdentity(origId);
5603    }
5604
5605    @Override
5606    public final void activityDestroyed(IBinder token) {
5607        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5608        synchronized (this) {
5609            ActivityStack stack = ActivityRecord.getStackLocked(token);
5610            if (stack != null) {
5611                stack.activityDestroyedLocked(token);
5612            }
5613        }
5614    }
5615
5616    @Override
5617    public final void mediaResourcesReleased(IBinder token) {
5618        final long origId = Binder.clearCallingIdentity();
5619        try {
5620            synchronized (this) {
5621                ActivityStack stack = ActivityRecord.getStackLocked(token);
5622                if (stack != null) {
5623                    stack.mediaResourcesReleased(token);
5624                }
5625            }
5626        } finally {
5627            Binder.restoreCallingIdentity(origId);
5628        }
5629    }
5630
5631    @Override
5632    public String getCallingPackage(IBinder token) {
5633        synchronized (this) {
5634            ActivityRecord r = getCallingRecordLocked(token);
5635            return r != null ? r.info.packageName : null;
5636        }
5637    }
5638
5639    @Override
5640    public ComponentName getCallingActivity(IBinder token) {
5641        synchronized (this) {
5642            ActivityRecord r = getCallingRecordLocked(token);
5643            return r != null ? r.intent.getComponent() : null;
5644        }
5645    }
5646
5647    private ActivityRecord getCallingRecordLocked(IBinder token) {
5648        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5649        if (r == null) {
5650            return null;
5651        }
5652        return r.resultTo;
5653    }
5654
5655    @Override
5656    public ComponentName getActivityClassForToken(IBinder token) {
5657        synchronized(this) {
5658            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5659            if (r == null) {
5660                return null;
5661            }
5662            return r.intent.getComponent();
5663        }
5664    }
5665
5666    @Override
5667    public String getPackageForToken(IBinder token) {
5668        synchronized(this) {
5669            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5670            if (r == null) {
5671                return null;
5672            }
5673            return r.packageName;
5674        }
5675    }
5676
5677    @Override
5678    public IIntentSender getIntentSender(int type,
5679            String packageName, IBinder token, String resultWho,
5680            int requestCode, Intent[] intents, String[] resolvedTypes,
5681            int flags, Bundle options, int userId) {
5682        enforceNotIsolatedCaller("getIntentSender");
5683        // Refuse possible leaked file descriptors
5684        if (intents != null) {
5685            if (intents.length < 1) {
5686                throw new IllegalArgumentException("Intents array length must be >= 1");
5687            }
5688            for (int i=0; i<intents.length; i++) {
5689                Intent intent = intents[i];
5690                if (intent != null) {
5691                    if (intent.hasFileDescriptors()) {
5692                        throw new IllegalArgumentException("File descriptors passed in Intent");
5693                    }
5694                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5695                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5696                        throw new IllegalArgumentException(
5697                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5698                    }
5699                    intents[i] = new Intent(intent);
5700                }
5701            }
5702            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5703                throw new IllegalArgumentException(
5704                        "Intent array length does not match resolvedTypes length");
5705            }
5706        }
5707        if (options != null) {
5708            if (options.hasFileDescriptors()) {
5709                throw new IllegalArgumentException("File descriptors passed in options");
5710            }
5711        }
5712
5713        synchronized(this) {
5714            int callingUid = Binder.getCallingUid();
5715            int origUserId = userId;
5716            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5717                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5718                    "getIntentSender", null);
5719            if (origUserId == UserHandle.USER_CURRENT) {
5720                // We don't want to evaluate this until the pending intent is
5721                // actually executed.  However, we do want to always do the
5722                // security checking for it above.
5723                userId = UserHandle.USER_CURRENT;
5724            }
5725            try {
5726                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5727                    int uid = AppGlobals.getPackageManager()
5728                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5729                    if (!UserHandle.isSameApp(callingUid, uid)) {
5730                        String msg = "Permission Denial: getIntentSender() from pid="
5731                            + Binder.getCallingPid()
5732                            + ", uid=" + Binder.getCallingUid()
5733                            + ", (need uid=" + uid + ")"
5734                            + " is not allowed to send as package " + packageName;
5735                        Slog.w(TAG, msg);
5736                        throw new SecurityException(msg);
5737                    }
5738                }
5739
5740                return getIntentSenderLocked(type, packageName, callingUid, userId,
5741                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5742
5743            } catch (RemoteException e) {
5744                throw new SecurityException(e);
5745            }
5746        }
5747    }
5748
5749    IIntentSender getIntentSenderLocked(int type, String packageName,
5750            int callingUid, int userId, IBinder token, String resultWho,
5751            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5752            Bundle options) {
5753        if (DEBUG_MU)
5754            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5755        ActivityRecord activity = null;
5756        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5757            activity = ActivityRecord.isInStackLocked(token);
5758            if (activity == null) {
5759                return null;
5760            }
5761            if (activity.finishing) {
5762                return null;
5763            }
5764        }
5765
5766        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5767        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5768        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5769        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5770                |PendingIntent.FLAG_UPDATE_CURRENT);
5771
5772        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5773                type, packageName, activity, resultWho,
5774                requestCode, intents, resolvedTypes, flags, options, userId);
5775        WeakReference<PendingIntentRecord> ref;
5776        ref = mIntentSenderRecords.get(key);
5777        PendingIntentRecord rec = ref != null ? ref.get() : null;
5778        if (rec != null) {
5779            if (!cancelCurrent) {
5780                if (updateCurrent) {
5781                    if (rec.key.requestIntent != null) {
5782                        rec.key.requestIntent.replaceExtras(intents != null ?
5783                                intents[intents.length - 1] : null);
5784                    }
5785                    if (intents != null) {
5786                        intents[intents.length-1] = rec.key.requestIntent;
5787                        rec.key.allIntents = intents;
5788                        rec.key.allResolvedTypes = resolvedTypes;
5789                    } else {
5790                        rec.key.allIntents = null;
5791                        rec.key.allResolvedTypes = null;
5792                    }
5793                }
5794                return rec;
5795            }
5796            rec.canceled = true;
5797            mIntentSenderRecords.remove(key);
5798        }
5799        if (noCreate) {
5800            return rec;
5801        }
5802        rec = new PendingIntentRecord(this, key, callingUid);
5803        mIntentSenderRecords.put(key, rec.ref);
5804        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5805            if (activity.pendingResults == null) {
5806                activity.pendingResults
5807                        = new HashSet<WeakReference<PendingIntentRecord>>();
5808            }
5809            activity.pendingResults.add(rec.ref);
5810        }
5811        return rec;
5812    }
5813
5814    @Override
5815    public void cancelIntentSender(IIntentSender sender) {
5816        if (!(sender instanceof PendingIntentRecord)) {
5817            return;
5818        }
5819        synchronized(this) {
5820            PendingIntentRecord rec = (PendingIntentRecord)sender;
5821            try {
5822                int uid = AppGlobals.getPackageManager()
5823                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5824                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5825                    String msg = "Permission Denial: cancelIntentSender() from pid="
5826                        + Binder.getCallingPid()
5827                        + ", uid=" + Binder.getCallingUid()
5828                        + " is not allowed to cancel packges "
5829                        + rec.key.packageName;
5830                    Slog.w(TAG, msg);
5831                    throw new SecurityException(msg);
5832                }
5833            } catch (RemoteException e) {
5834                throw new SecurityException(e);
5835            }
5836            cancelIntentSenderLocked(rec, true);
5837        }
5838    }
5839
5840    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5841        rec.canceled = true;
5842        mIntentSenderRecords.remove(rec.key);
5843        if (cleanActivity && rec.key.activity != null) {
5844            rec.key.activity.pendingResults.remove(rec.ref);
5845        }
5846    }
5847
5848    @Override
5849    public String getPackageForIntentSender(IIntentSender pendingResult) {
5850        if (!(pendingResult instanceof PendingIntentRecord)) {
5851            return null;
5852        }
5853        try {
5854            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5855            return res.key.packageName;
5856        } catch (ClassCastException e) {
5857        }
5858        return null;
5859    }
5860
5861    @Override
5862    public int getUidForIntentSender(IIntentSender sender) {
5863        if (sender instanceof PendingIntentRecord) {
5864            try {
5865                PendingIntentRecord res = (PendingIntentRecord)sender;
5866                return res.uid;
5867            } catch (ClassCastException e) {
5868            }
5869        }
5870        return -1;
5871    }
5872
5873    @Override
5874    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5875        if (!(pendingResult instanceof PendingIntentRecord)) {
5876            return false;
5877        }
5878        try {
5879            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5880            if (res.key.allIntents == null) {
5881                return false;
5882            }
5883            for (int i=0; i<res.key.allIntents.length; i++) {
5884                Intent intent = res.key.allIntents[i];
5885                if (intent.getPackage() != null && intent.getComponent() != null) {
5886                    return false;
5887                }
5888            }
5889            return true;
5890        } catch (ClassCastException e) {
5891        }
5892        return false;
5893    }
5894
5895    @Override
5896    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5897        if (!(pendingResult instanceof PendingIntentRecord)) {
5898            return false;
5899        }
5900        try {
5901            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5902            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5903                return true;
5904            }
5905            return false;
5906        } catch (ClassCastException e) {
5907        }
5908        return false;
5909    }
5910
5911    @Override
5912    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5913        if (!(pendingResult instanceof PendingIntentRecord)) {
5914            return null;
5915        }
5916        try {
5917            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5918            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5919        } catch (ClassCastException e) {
5920        }
5921        return null;
5922    }
5923
5924    @Override
5925    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5926        if (!(pendingResult instanceof PendingIntentRecord)) {
5927            return null;
5928        }
5929        try {
5930            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5931            Intent intent = res.key.requestIntent;
5932            if (intent != null) {
5933                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5934                        || res.lastTagPrefix.equals(prefix))) {
5935                    return res.lastTag;
5936                }
5937                res.lastTagPrefix = prefix;
5938                StringBuilder sb = new StringBuilder(128);
5939                if (prefix != null) {
5940                    sb.append(prefix);
5941                }
5942                if (intent.getAction() != null) {
5943                    sb.append(intent.getAction());
5944                } else if (intent.getComponent() != null) {
5945                    intent.getComponent().appendShortString(sb);
5946                } else {
5947                    sb.append("?");
5948                }
5949                return res.lastTag = sb.toString();
5950            }
5951        } catch (ClassCastException e) {
5952        }
5953        return null;
5954    }
5955
5956    @Override
5957    public void setProcessLimit(int max) {
5958        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5959                "setProcessLimit()");
5960        synchronized (this) {
5961            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5962            mProcessLimitOverride = max;
5963        }
5964        trimApplications();
5965    }
5966
5967    @Override
5968    public int getProcessLimit() {
5969        synchronized (this) {
5970            return mProcessLimitOverride;
5971        }
5972    }
5973
5974    void foregroundTokenDied(ForegroundToken token) {
5975        synchronized (ActivityManagerService.this) {
5976            synchronized (mPidsSelfLocked) {
5977                ForegroundToken cur
5978                    = mForegroundProcesses.get(token.pid);
5979                if (cur != token) {
5980                    return;
5981                }
5982                mForegroundProcesses.remove(token.pid);
5983                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5984                if (pr == null) {
5985                    return;
5986                }
5987                pr.forcingToForeground = null;
5988                updateProcessForegroundLocked(pr, false, false);
5989            }
5990            updateOomAdjLocked();
5991        }
5992    }
5993
5994    @Override
5995    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5996        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5997                "setProcessForeground()");
5998        synchronized(this) {
5999            boolean changed = false;
6000
6001            synchronized (mPidsSelfLocked) {
6002                ProcessRecord pr = mPidsSelfLocked.get(pid);
6003                if (pr == null && isForeground) {
6004                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6005                    return;
6006                }
6007                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6008                if (oldToken != null) {
6009                    oldToken.token.unlinkToDeath(oldToken, 0);
6010                    mForegroundProcesses.remove(pid);
6011                    if (pr != null) {
6012                        pr.forcingToForeground = null;
6013                    }
6014                    changed = true;
6015                }
6016                if (isForeground && token != null) {
6017                    ForegroundToken newToken = new ForegroundToken() {
6018                        @Override
6019                        public void binderDied() {
6020                            foregroundTokenDied(this);
6021                        }
6022                    };
6023                    newToken.pid = pid;
6024                    newToken.token = token;
6025                    try {
6026                        token.linkToDeath(newToken, 0);
6027                        mForegroundProcesses.put(pid, newToken);
6028                        pr.forcingToForeground = token;
6029                        changed = true;
6030                    } catch (RemoteException e) {
6031                        // If the process died while doing this, we will later
6032                        // do the cleanup with the process death link.
6033                    }
6034                }
6035            }
6036
6037            if (changed) {
6038                updateOomAdjLocked();
6039            }
6040        }
6041    }
6042
6043    // =========================================================
6044    // PERMISSIONS
6045    // =========================================================
6046
6047    static class PermissionController extends IPermissionController.Stub {
6048        ActivityManagerService mActivityManagerService;
6049        PermissionController(ActivityManagerService activityManagerService) {
6050            mActivityManagerService = activityManagerService;
6051        }
6052
6053        @Override
6054        public boolean checkPermission(String permission, int pid, int uid) {
6055            return mActivityManagerService.checkPermission(permission, pid,
6056                    uid) == PackageManager.PERMISSION_GRANTED;
6057        }
6058    }
6059
6060    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6061        @Override
6062        public int checkComponentPermission(String permission, int pid, int uid,
6063                int owningUid, boolean exported) {
6064            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6065                    owningUid, exported);
6066        }
6067
6068        @Override
6069        public Object getAMSLock() {
6070            return ActivityManagerService.this;
6071        }
6072    }
6073
6074    /**
6075     * This can be called with or without the global lock held.
6076     */
6077    int checkComponentPermission(String permission, int pid, int uid,
6078            int owningUid, boolean exported) {
6079        // We might be performing an operation on behalf of an indirect binder
6080        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6081        // client identity accordingly before proceeding.
6082        Identity tlsIdentity = sCallerIdentity.get();
6083        if (tlsIdentity != null) {
6084            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6085                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6086            uid = tlsIdentity.uid;
6087            pid = tlsIdentity.pid;
6088        }
6089
6090        if (pid == MY_PID) {
6091            return PackageManager.PERMISSION_GRANTED;
6092        }
6093
6094        return ActivityManager.checkComponentPermission(permission, uid,
6095                owningUid, exported);
6096    }
6097
6098    /**
6099     * As the only public entry point for permissions checking, this method
6100     * can enforce the semantic that requesting a check on a null global
6101     * permission is automatically denied.  (Internally a null permission
6102     * string is used when calling {@link #checkComponentPermission} in cases
6103     * when only uid-based security is needed.)
6104     *
6105     * This can be called with or without the global lock held.
6106     */
6107    @Override
6108    public int checkPermission(String permission, int pid, int uid) {
6109        if (permission == null) {
6110            return PackageManager.PERMISSION_DENIED;
6111        }
6112        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6113    }
6114
6115    /**
6116     * Binder IPC calls go through the public entry point.
6117     * This can be called with or without the global lock held.
6118     */
6119    int checkCallingPermission(String permission) {
6120        return checkPermission(permission,
6121                Binder.getCallingPid(),
6122                UserHandle.getAppId(Binder.getCallingUid()));
6123    }
6124
6125    /**
6126     * This can be called with or without the global lock held.
6127     */
6128    void enforceCallingPermission(String permission, String func) {
6129        if (checkCallingPermission(permission)
6130                == PackageManager.PERMISSION_GRANTED) {
6131            return;
6132        }
6133
6134        String msg = "Permission Denial: " + func + " from pid="
6135                + Binder.getCallingPid()
6136                + ", uid=" + Binder.getCallingUid()
6137                + " requires " + permission;
6138        Slog.w(TAG, msg);
6139        throw new SecurityException(msg);
6140    }
6141
6142    /**
6143     * Determine if UID is holding permissions required to access {@link Uri} in
6144     * the given {@link ProviderInfo}. Final permission checking is always done
6145     * in {@link ContentProvider}.
6146     */
6147    private final boolean checkHoldingPermissionsLocked(
6148            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6149        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6150                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6151        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6152            return false;
6153        }
6154        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6155    }
6156
6157    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6158            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6159        if (pi.applicationInfo.uid == uid) {
6160            return true;
6161        } else if (!pi.exported) {
6162            return false;
6163        }
6164
6165        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6166        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6167        try {
6168            // check if target holds top-level <provider> permissions
6169            if (!readMet && pi.readPermission != null && considerUidPermissions
6170                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6171                readMet = true;
6172            }
6173            if (!writeMet && pi.writePermission != null && considerUidPermissions
6174                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6175                writeMet = true;
6176            }
6177
6178            // track if unprotected read/write is allowed; any denied
6179            // <path-permission> below removes this ability
6180            boolean allowDefaultRead = pi.readPermission == null;
6181            boolean allowDefaultWrite = pi.writePermission == null;
6182
6183            // check if target holds any <path-permission> that match uri
6184            final PathPermission[] pps = pi.pathPermissions;
6185            if (pps != null) {
6186                final String path = grantUri.uri.getPath();
6187                int i = pps.length;
6188                while (i > 0 && (!readMet || !writeMet)) {
6189                    i--;
6190                    PathPermission pp = pps[i];
6191                    if (pp.match(path)) {
6192                        if (!readMet) {
6193                            final String pprperm = pp.getReadPermission();
6194                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6195                                    + pprperm + " for " + pp.getPath()
6196                                    + ": match=" + pp.match(path)
6197                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6198                            if (pprperm != null) {
6199                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6200                                        == PERMISSION_GRANTED) {
6201                                    readMet = true;
6202                                } else {
6203                                    allowDefaultRead = false;
6204                                }
6205                            }
6206                        }
6207                        if (!writeMet) {
6208                            final String ppwperm = pp.getWritePermission();
6209                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6210                                    + ppwperm + " for " + pp.getPath()
6211                                    + ": match=" + pp.match(path)
6212                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6213                            if (ppwperm != null) {
6214                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6215                                        == PERMISSION_GRANTED) {
6216                                    writeMet = true;
6217                                } else {
6218                                    allowDefaultWrite = false;
6219                                }
6220                            }
6221                        }
6222                    }
6223                }
6224            }
6225
6226            // grant unprotected <provider> read/write, if not blocked by
6227            // <path-permission> above
6228            if (allowDefaultRead) readMet = true;
6229            if (allowDefaultWrite) writeMet = true;
6230
6231        } catch (RemoteException e) {
6232            return false;
6233        }
6234
6235        return readMet && writeMet;
6236    }
6237
6238    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6239        ProviderInfo pi = null;
6240        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6241        if (cpr != null) {
6242            pi = cpr.info;
6243        } else {
6244            try {
6245                pi = AppGlobals.getPackageManager().resolveContentProvider(
6246                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6247            } catch (RemoteException ex) {
6248            }
6249        }
6250        return pi;
6251    }
6252
6253    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6254        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6255        if (targetUris != null) {
6256            return targetUris.get(grantUri);
6257        }
6258        return null;
6259    }
6260
6261    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6262            String targetPkg, int targetUid, GrantUri grantUri) {
6263        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6264        if (targetUris == null) {
6265            targetUris = Maps.newArrayMap();
6266            mGrantedUriPermissions.put(targetUid, targetUris);
6267        }
6268
6269        UriPermission perm = targetUris.get(grantUri);
6270        if (perm == null) {
6271            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6272            targetUris.put(grantUri, perm);
6273        }
6274
6275        return perm;
6276    }
6277
6278    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6279            final int modeFlags) {
6280        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6281        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6282                : UriPermission.STRENGTH_OWNED;
6283
6284        // Root gets to do everything.
6285        if (uid == 0) {
6286            return true;
6287        }
6288
6289        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6290        if (perms == null) return false;
6291
6292        // First look for exact match
6293        final UriPermission exactPerm = perms.get(grantUri);
6294        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6295            return true;
6296        }
6297
6298        // No exact match, look for prefixes
6299        final int N = perms.size();
6300        for (int i = 0; i < N; i++) {
6301            final UriPermission perm = perms.valueAt(i);
6302            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6303                    && perm.getStrength(modeFlags) >= minStrength) {
6304                return true;
6305            }
6306        }
6307
6308        return false;
6309    }
6310
6311    @Override
6312    public int checkUriPermission(Uri uri, int pid, int uid,
6313            final int modeFlags, int userId) {
6314        enforceNotIsolatedCaller("checkUriPermission");
6315
6316        // Another redirected-binder-call permissions check as in
6317        // {@link checkComponentPermission}.
6318        Identity tlsIdentity = sCallerIdentity.get();
6319        if (tlsIdentity != null) {
6320            uid = tlsIdentity.uid;
6321            pid = tlsIdentity.pid;
6322        }
6323
6324        // Our own process gets to do everything.
6325        if (pid == MY_PID) {
6326            return PackageManager.PERMISSION_GRANTED;
6327        }
6328        synchronized (this) {
6329            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6330                    ? PackageManager.PERMISSION_GRANTED
6331                    : PackageManager.PERMISSION_DENIED;
6332        }
6333    }
6334
6335    /**
6336     * Check if the targetPkg can be granted permission to access uri by
6337     * the callingUid using the given modeFlags.  Throws a security exception
6338     * if callingUid is not allowed to do this.  Returns the uid of the target
6339     * if the URI permission grant should be performed; returns -1 if it is not
6340     * needed (for example targetPkg already has permission to access the URI).
6341     * If you already know the uid of the target, you can supply it in
6342     * lastTargetUid else set that to -1.
6343     */
6344    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6345            final int modeFlags, int lastTargetUid) {
6346        if (!Intent.isAccessUriMode(modeFlags)) {
6347            return -1;
6348        }
6349
6350        if (targetPkg != null) {
6351            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6352                    "Checking grant " + targetPkg + " permission to " + grantUri);
6353        }
6354
6355        final IPackageManager pm = AppGlobals.getPackageManager();
6356
6357        // If this is not a content: uri, we can't do anything with it.
6358        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6359            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6360                    "Can't grant URI permission for non-content URI: " + grantUri);
6361            return -1;
6362        }
6363
6364        final String authority = grantUri.uri.getAuthority();
6365        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6366        if (pi == null) {
6367            Slog.w(TAG, "No content provider found for permission check: " +
6368                    grantUri.uri.toSafeString());
6369            return -1;
6370        }
6371
6372        int targetUid = lastTargetUid;
6373        if (targetUid < 0 && targetPkg != null) {
6374            try {
6375                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6376                if (targetUid < 0) {
6377                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6378                            "Can't grant URI permission no uid for: " + targetPkg);
6379                    return -1;
6380                }
6381            } catch (RemoteException ex) {
6382                return -1;
6383            }
6384        }
6385
6386        if (targetUid >= 0) {
6387            // First...  does the target actually need this permission?
6388            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6389                // No need to grant the target this permission.
6390                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6391                        "Target " + targetPkg + " already has full permission to " + grantUri);
6392                return -1;
6393            }
6394        } else {
6395            // First...  there is no target package, so can anyone access it?
6396            boolean allowed = pi.exported;
6397            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6398                if (pi.readPermission != null) {
6399                    allowed = false;
6400                }
6401            }
6402            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6403                if (pi.writePermission != null) {
6404                    allowed = false;
6405                }
6406            }
6407            if (allowed) {
6408                return -1;
6409            }
6410        }
6411
6412        /* There is a special cross user grant if:
6413         * - The target is on another user.
6414         * - Apps on the current user can access the uri without any uid permissions.
6415         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6416         * grant uri permissions.
6417         */
6418        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6419                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6420                modeFlags, false /*without considering the uid permissions*/);
6421
6422        // Second...  is the provider allowing granting of URI permissions?
6423        if (!specialCrossUserGrant) {
6424            if (!pi.grantUriPermissions) {
6425                throw new SecurityException("Provider " + pi.packageName
6426                        + "/" + pi.name
6427                        + " does not allow granting of Uri permissions (uri "
6428                        + grantUri + ")");
6429            }
6430            if (pi.uriPermissionPatterns != null) {
6431                final int N = pi.uriPermissionPatterns.length;
6432                boolean allowed = false;
6433                for (int i=0; i<N; i++) {
6434                    if (pi.uriPermissionPatterns[i] != null
6435                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6436                        allowed = true;
6437                        break;
6438                    }
6439                }
6440                if (!allowed) {
6441                    throw new SecurityException("Provider " + pi.packageName
6442                            + "/" + pi.name
6443                            + " does not allow granting of permission to path of Uri "
6444                            + grantUri);
6445                }
6446            }
6447        }
6448
6449        // Third...  does the caller itself have permission to access
6450        // this uri?
6451        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6452            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6453                // Require they hold a strong enough Uri permission
6454                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6455                    throw new SecurityException("Uid " + callingUid
6456                            + " does not have permission to uri " + grantUri);
6457                }
6458            }
6459        }
6460        return targetUid;
6461    }
6462
6463    @Override
6464    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6465            final int modeFlags, int userId) {
6466        enforceNotIsolatedCaller("checkGrantUriPermission");
6467        synchronized(this) {
6468            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6469                    new GrantUri(userId, uri, false), modeFlags, -1);
6470        }
6471    }
6472
6473    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6474            final int modeFlags, UriPermissionOwner owner) {
6475        if (!Intent.isAccessUriMode(modeFlags)) {
6476            return;
6477        }
6478
6479        // So here we are: the caller has the assumed permission
6480        // to the uri, and the target doesn't.  Let's now give this to
6481        // the target.
6482
6483        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6484                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6485
6486        final String authority = grantUri.uri.getAuthority();
6487        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6488        if (pi == null) {
6489            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6490            return;
6491        }
6492
6493        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6494            grantUri.prefix = true;
6495        }
6496        final UriPermission perm = findOrCreateUriPermissionLocked(
6497                pi.packageName, targetPkg, targetUid, grantUri);
6498        perm.grantModes(modeFlags, owner);
6499    }
6500
6501    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6502            final int modeFlags, UriPermissionOwner owner) {
6503        if (targetPkg == null) {
6504            throw new NullPointerException("targetPkg");
6505        }
6506
6507        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6508                -1);
6509        if (targetUid < 0) {
6510            return;
6511        }
6512
6513        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6514                owner);
6515    }
6516
6517    static class NeededUriGrants extends ArrayList<GrantUri> {
6518        final String targetPkg;
6519        final int targetUid;
6520        final int flags;
6521
6522        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6523            this.targetPkg = targetPkg;
6524            this.targetUid = targetUid;
6525            this.flags = flags;
6526        }
6527    }
6528
6529    /**
6530     * Like checkGrantUriPermissionLocked, but takes an Intent.
6531     */
6532    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6533            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6534        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6535                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6536                + " clip=" + (intent != null ? intent.getClipData() : null)
6537                + " from " + intent + "; flags=0x"
6538                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6539
6540        if (targetPkg == null) {
6541            throw new NullPointerException("targetPkg");
6542        }
6543
6544        if (intent == null) {
6545            return null;
6546        }
6547        Uri data = intent.getData();
6548        ClipData clip = intent.getClipData();
6549        if (data == null && clip == null) {
6550            return null;
6551        }
6552        final IPackageManager pm = AppGlobals.getPackageManager();
6553        int targetUid;
6554        if (needed != null) {
6555            targetUid = needed.targetUid;
6556        } else {
6557            try {
6558                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6559            } catch (RemoteException ex) {
6560                return null;
6561            }
6562            if (targetUid < 0) {
6563                if (DEBUG_URI_PERMISSION) {
6564                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6565                            + " on user " + targetUserId);
6566                }
6567                return null;
6568            }
6569        }
6570        if (data != null) {
6571            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6572            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6573                    targetUid);
6574            if (targetUid > 0) {
6575                if (needed == null) {
6576                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6577                }
6578                needed.add(grantUri);
6579            }
6580        }
6581        if (clip != null) {
6582            for (int i=0; i<clip.getItemCount(); i++) {
6583                Uri uri = clip.getItemAt(i).getUri();
6584                if (uri != null) {
6585                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6586                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6587                            targetUid);
6588                    if (targetUid > 0) {
6589                        if (needed == null) {
6590                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6591                        }
6592                        needed.add(grantUri);
6593                    }
6594                } else {
6595                    Intent clipIntent = clip.getItemAt(i).getIntent();
6596                    if (clipIntent != null) {
6597                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6598                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6599                        if (newNeeded != null) {
6600                            needed = newNeeded;
6601                        }
6602                    }
6603                }
6604            }
6605        }
6606
6607        return needed;
6608    }
6609
6610    /**
6611     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6612     */
6613    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6614            UriPermissionOwner owner) {
6615        if (needed != null) {
6616            for (int i=0; i<needed.size(); i++) {
6617                GrantUri grantUri = needed.get(i);
6618                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6619                        grantUri, needed.flags, owner);
6620            }
6621        }
6622    }
6623
6624    void grantUriPermissionFromIntentLocked(int callingUid,
6625            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6626        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6627                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6628        if (needed == null) {
6629            return;
6630        }
6631
6632        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6633    }
6634
6635    @Override
6636    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6637            final int modeFlags, int userId) {
6638        enforceNotIsolatedCaller("grantUriPermission");
6639        GrantUri grantUri = new GrantUri(userId, uri, false);
6640        synchronized(this) {
6641            final ProcessRecord r = getRecordForAppLocked(caller);
6642            if (r == null) {
6643                throw new SecurityException("Unable to find app for caller "
6644                        + caller
6645                        + " when granting permission to uri " + grantUri);
6646            }
6647            if (targetPkg == null) {
6648                throw new IllegalArgumentException("null target");
6649            }
6650            if (grantUri == null) {
6651                throw new IllegalArgumentException("null uri");
6652            }
6653
6654            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6655                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6656                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6657                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6658
6659            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6660        }
6661    }
6662
6663    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6664        if (perm.modeFlags == 0) {
6665            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6666                    perm.targetUid);
6667            if (perms != null) {
6668                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6669                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6670
6671                perms.remove(perm.uri);
6672                if (perms.isEmpty()) {
6673                    mGrantedUriPermissions.remove(perm.targetUid);
6674                }
6675            }
6676        }
6677    }
6678
6679    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6680        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6681
6682        final IPackageManager pm = AppGlobals.getPackageManager();
6683        final String authority = grantUri.uri.getAuthority();
6684        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6685        if (pi == null) {
6686            Slog.w(TAG, "No content provider found for permission revoke: "
6687                    + grantUri.toSafeString());
6688            return;
6689        }
6690
6691        // Does the caller have this permission on the URI?
6692        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6693            // Right now, if you are not the original owner of the permission,
6694            // you are not allowed to revoke it.
6695            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6696                throw new SecurityException("Uid " + callingUid
6697                        + " does not have permission to uri " + grantUri);
6698            //}
6699        }
6700
6701        boolean persistChanged = false;
6702
6703        // Go through all of the permissions and remove any that match.
6704        int N = mGrantedUriPermissions.size();
6705        for (int i = 0; i < N; i++) {
6706            final int targetUid = mGrantedUriPermissions.keyAt(i);
6707            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6708
6709            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6710                final UriPermission perm = it.next();
6711                if (perm.uri.sourceUserId == grantUri.sourceUserId
6712                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6713                    if (DEBUG_URI_PERMISSION)
6714                        Slog.v(TAG,
6715                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6716                    persistChanged |= perm.revokeModes(
6717                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6718                    if (perm.modeFlags == 0) {
6719                        it.remove();
6720                    }
6721                }
6722            }
6723
6724            if (perms.isEmpty()) {
6725                mGrantedUriPermissions.remove(targetUid);
6726                N--;
6727                i--;
6728            }
6729        }
6730
6731        if (persistChanged) {
6732            schedulePersistUriGrants();
6733        }
6734    }
6735
6736    @Override
6737    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6738            int userId) {
6739        enforceNotIsolatedCaller("revokeUriPermission");
6740        synchronized(this) {
6741            final ProcessRecord r = getRecordForAppLocked(caller);
6742            if (r == null) {
6743                throw new SecurityException("Unable to find app for caller "
6744                        + caller
6745                        + " when revoking permission to uri " + uri);
6746            }
6747            if (uri == null) {
6748                Slog.w(TAG, "revokeUriPermission: null uri");
6749                return;
6750            }
6751
6752            if (!Intent.isAccessUriMode(modeFlags)) {
6753                return;
6754            }
6755
6756            final IPackageManager pm = AppGlobals.getPackageManager();
6757            final String authority = uri.getAuthority();
6758            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6759            if (pi == null) {
6760                Slog.w(TAG, "No content provider found for permission revoke: "
6761                        + uri.toSafeString());
6762                return;
6763            }
6764
6765            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6766        }
6767    }
6768
6769    /**
6770     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6771     * given package.
6772     *
6773     * @param packageName Package name to match, or {@code null} to apply to all
6774     *            packages.
6775     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6776     *            to all users.
6777     * @param persistable If persistable grants should be removed.
6778     */
6779    private void removeUriPermissionsForPackageLocked(
6780            String packageName, int userHandle, boolean persistable) {
6781        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6782            throw new IllegalArgumentException("Must narrow by either package or user");
6783        }
6784
6785        boolean persistChanged = false;
6786
6787        int N = mGrantedUriPermissions.size();
6788        for (int i = 0; i < N; i++) {
6789            final int targetUid = mGrantedUriPermissions.keyAt(i);
6790            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6791
6792            // Only inspect grants matching user
6793            if (userHandle == UserHandle.USER_ALL
6794                    || userHandle == UserHandle.getUserId(targetUid)) {
6795                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6796                    final UriPermission perm = it.next();
6797
6798                    // Only inspect grants matching package
6799                    if (packageName == null || perm.sourcePkg.equals(packageName)
6800                            || perm.targetPkg.equals(packageName)) {
6801                        persistChanged |= perm.revokeModes(
6802                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6803
6804                        // Only remove when no modes remain; any persisted grants
6805                        // will keep this alive.
6806                        if (perm.modeFlags == 0) {
6807                            it.remove();
6808                        }
6809                    }
6810                }
6811
6812                if (perms.isEmpty()) {
6813                    mGrantedUriPermissions.remove(targetUid);
6814                    N--;
6815                    i--;
6816                }
6817            }
6818        }
6819
6820        if (persistChanged) {
6821            schedulePersistUriGrants();
6822        }
6823    }
6824
6825    @Override
6826    public IBinder newUriPermissionOwner(String name) {
6827        enforceNotIsolatedCaller("newUriPermissionOwner");
6828        synchronized(this) {
6829            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6830            return owner.getExternalTokenLocked();
6831        }
6832    }
6833
6834    @Override
6835    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6836            final int modeFlags, int userId) {
6837        synchronized(this) {
6838            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6839            if (owner == null) {
6840                throw new IllegalArgumentException("Unknown owner: " + token);
6841            }
6842            if (fromUid != Binder.getCallingUid()) {
6843                if (Binder.getCallingUid() != Process.myUid()) {
6844                    // Only system code can grant URI permissions on behalf
6845                    // of other users.
6846                    throw new SecurityException("nice try");
6847                }
6848            }
6849            if (targetPkg == null) {
6850                throw new IllegalArgumentException("null target");
6851            }
6852            if (uri == null) {
6853                throw new IllegalArgumentException("null uri");
6854            }
6855
6856            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6857                    modeFlags, owner);
6858        }
6859    }
6860
6861    @Override
6862    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6863        synchronized(this) {
6864            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6865            if (owner == null) {
6866                throw new IllegalArgumentException("Unknown owner: " + token);
6867            }
6868
6869            if (uri == null) {
6870                owner.removeUriPermissionsLocked(mode);
6871            } else {
6872                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6873            }
6874        }
6875    }
6876
6877    private void schedulePersistUriGrants() {
6878        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6879            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6880                    10 * DateUtils.SECOND_IN_MILLIS);
6881        }
6882    }
6883
6884    private void writeGrantedUriPermissions() {
6885        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6886
6887        // Snapshot permissions so we can persist without lock
6888        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6889        synchronized (this) {
6890            final int size = mGrantedUriPermissions.size();
6891            for (int i = 0; i < size; i++) {
6892                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6893                for (UriPermission perm : perms.values()) {
6894                    if (perm.persistedModeFlags != 0) {
6895                        persist.add(perm.snapshot());
6896                    }
6897                }
6898            }
6899        }
6900
6901        FileOutputStream fos = null;
6902        try {
6903            fos = mGrantFile.startWrite();
6904
6905            XmlSerializer out = new FastXmlSerializer();
6906            out.setOutput(fos, "utf-8");
6907            out.startDocument(null, true);
6908            out.startTag(null, TAG_URI_GRANTS);
6909            for (UriPermission.Snapshot perm : persist) {
6910                out.startTag(null, TAG_URI_GRANT);
6911                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6912                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6913                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6914                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6915                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6916                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6917                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6918                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6919                out.endTag(null, TAG_URI_GRANT);
6920            }
6921            out.endTag(null, TAG_URI_GRANTS);
6922            out.endDocument();
6923
6924            mGrantFile.finishWrite(fos);
6925        } catch (IOException e) {
6926            if (fos != null) {
6927                mGrantFile.failWrite(fos);
6928            }
6929        }
6930    }
6931
6932    private void readGrantedUriPermissionsLocked() {
6933        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6934
6935        final long now = System.currentTimeMillis();
6936
6937        FileInputStream fis = null;
6938        try {
6939            fis = mGrantFile.openRead();
6940            final XmlPullParser in = Xml.newPullParser();
6941            in.setInput(fis, null);
6942
6943            int type;
6944            while ((type = in.next()) != END_DOCUMENT) {
6945                final String tag = in.getName();
6946                if (type == START_TAG) {
6947                    if (TAG_URI_GRANT.equals(tag)) {
6948                        final int sourceUserId;
6949                        final int targetUserId;
6950                        final int userHandle = readIntAttribute(in,
6951                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6952                        if (userHandle != UserHandle.USER_NULL) {
6953                            // For backwards compatibility.
6954                            sourceUserId = userHandle;
6955                            targetUserId = userHandle;
6956                        } else {
6957                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6958                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6959                        }
6960                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6961                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6962                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6963                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6964                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6965                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6966
6967                        // Sanity check that provider still belongs to source package
6968                        final ProviderInfo pi = getProviderInfoLocked(
6969                                uri.getAuthority(), sourceUserId);
6970                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6971                            int targetUid = -1;
6972                            try {
6973                                targetUid = AppGlobals.getPackageManager()
6974                                        .getPackageUid(targetPkg, targetUserId);
6975                            } catch (RemoteException e) {
6976                            }
6977                            if (targetUid != -1) {
6978                                final UriPermission perm = findOrCreateUriPermissionLocked(
6979                                        sourcePkg, targetPkg, targetUid,
6980                                        new GrantUri(sourceUserId, uri, prefix));
6981                                perm.initPersistedModes(modeFlags, createdTime);
6982                            }
6983                        } else {
6984                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6985                                    + " but instead found " + pi);
6986                        }
6987                    }
6988                }
6989            }
6990        } catch (FileNotFoundException e) {
6991            // Missing grants is okay
6992        } catch (IOException e) {
6993            Log.wtf(TAG, "Failed reading Uri grants", e);
6994        } catch (XmlPullParserException e) {
6995            Log.wtf(TAG, "Failed reading Uri grants", e);
6996        } finally {
6997            IoUtils.closeQuietly(fis);
6998        }
6999    }
7000
7001    @Override
7002    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7003        enforceNotIsolatedCaller("takePersistableUriPermission");
7004
7005        Preconditions.checkFlagsArgument(modeFlags,
7006                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7007
7008        synchronized (this) {
7009            final int callingUid = Binder.getCallingUid();
7010            boolean persistChanged = false;
7011            GrantUri grantUri = new GrantUri(userId, uri, false);
7012
7013            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7014                    new GrantUri(userId, uri, false));
7015            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7016                    new GrantUri(userId, uri, true));
7017
7018            final boolean exactValid = (exactPerm != null)
7019                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7020            final boolean prefixValid = (prefixPerm != null)
7021                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7022
7023            if (!(exactValid || prefixValid)) {
7024                throw new SecurityException("No persistable permission grants found for UID "
7025                        + callingUid + " and Uri " + grantUri.toSafeString());
7026            }
7027
7028            if (exactValid) {
7029                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7030            }
7031            if (prefixValid) {
7032                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7033            }
7034
7035            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7036
7037            if (persistChanged) {
7038                schedulePersistUriGrants();
7039            }
7040        }
7041    }
7042
7043    @Override
7044    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7045        enforceNotIsolatedCaller("releasePersistableUriPermission");
7046
7047        Preconditions.checkFlagsArgument(modeFlags,
7048                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7049
7050        synchronized (this) {
7051            final int callingUid = Binder.getCallingUid();
7052            boolean persistChanged = false;
7053
7054            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7055                    new GrantUri(userId, uri, false));
7056            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7057                    new GrantUri(userId, uri, true));
7058            if (exactPerm == null && prefixPerm == null) {
7059                throw new SecurityException("No permission grants found for UID " + callingUid
7060                        + " and Uri " + uri.toSafeString());
7061            }
7062
7063            if (exactPerm != null) {
7064                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7065                removeUriPermissionIfNeededLocked(exactPerm);
7066            }
7067            if (prefixPerm != null) {
7068                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7069                removeUriPermissionIfNeededLocked(prefixPerm);
7070            }
7071
7072            if (persistChanged) {
7073                schedulePersistUriGrants();
7074            }
7075        }
7076    }
7077
7078    /**
7079     * Prune any older {@link UriPermission} for the given UID until outstanding
7080     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7081     *
7082     * @return if any mutations occured that require persisting.
7083     */
7084    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7085        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7086        if (perms == null) return false;
7087        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7088
7089        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7090        for (UriPermission perm : perms.values()) {
7091            if (perm.persistedModeFlags != 0) {
7092                persisted.add(perm);
7093            }
7094        }
7095
7096        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7097        if (trimCount <= 0) return false;
7098
7099        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7100        for (int i = 0; i < trimCount; i++) {
7101            final UriPermission perm = persisted.get(i);
7102
7103            if (DEBUG_URI_PERMISSION) {
7104                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7105            }
7106
7107            perm.releasePersistableModes(~0);
7108            removeUriPermissionIfNeededLocked(perm);
7109        }
7110
7111        return true;
7112    }
7113
7114    @Override
7115    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7116            String packageName, boolean incoming) {
7117        enforceNotIsolatedCaller("getPersistedUriPermissions");
7118        Preconditions.checkNotNull(packageName, "packageName");
7119
7120        final int callingUid = Binder.getCallingUid();
7121        final IPackageManager pm = AppGlobals.getPackageManager();
7122        try {
7123            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7124            if (packageUid != callingUid) {
7125                throw new SecurityException(
7126                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7127            }
7128        } catch (RemoteException e) {
7129            throw new SecurityException("Failed to verify package name ownership");
7130        }
7131
7132        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7133        synchronized (this) {
7134            if (incoming) {
7135                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7136                        callingUid);
7137                if (perms == null) {
7138                    Slog.w(TAG, "No permission grants found for " + packageName);
7139                } else {
7140                    for (UriPermission perm : perms.values()) {
7141                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7142                            result.add(perm.buildPersistedPublicApiObject());
7143                        }
7144                    }
7145                }
7146            } else {
7147                final int size = mGrantedUriPermissions.size();
7148                for (int i = 0; i < size; i++) {
7149                    final ArrayMap<GrantUri, UriPermission> perms =
7150                            mGrantedUriPermissions.valueAt(i);
7151                    for (UriPermission perm : perms.values()) {
7152                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7153                            result.add(perm.buildPersistedPublicApiObject());
7154                        }
7155                    }
7156                }
7157            }
7158        }
7159        return new ParceledListSlice<android.content.UriPermission>(result);
7160    }
7161
7162    @Override
7163    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7164        synchronized (this) {
7165            ProcessRecord app =
7166                who != null ? getRecordForAppLocked(who) : null;
7167            if (app == null) return;
7168
7169            Message msg = Message.obtain();
7170            msg.what = WAIT_FOR_DEBUGGER_MSG;
7171            msg.obj = app;
7172            msg.arg1 = waiting ? 1 : 0;
7173            mHandler.sendMessage(msg);
7174        }
7175    }
7176
7177    @Override
7178    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7179        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7180        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7181        outInfo.availMem = Process.getFreeMemory();
7182        outInfo.totalMem = Process.getTotalMemory();
7183        outInfo.threshold = homeAppMem;
7184        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7185        outInfo.hiddenAppThreshold = cachedAppMem;
7186        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7187                ProcessList.SERVICE_ADJ);
7188        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7189                ProcessList.VISIBLE_APP_ADJ);
7190        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7191                ProcessList.FOREGROUND_APP_ADJ);
7192    }
7193
7194    // =========================================================
7195    // TASK MANAGEMENT
7196    // =========================================================
7197
7198    @Override
7199    public List<IAppTask> getAppTasks() {
7200        final PackageManager pm = mContext.getPackageManager();
7201        int callingUid = Binder.getCallingUid();
7202        long ident = Binder.clearCallingIdentity();
7203
7204        // Compose the list of packages for this id to test against
7205        HashSet<String> packages = new HashSet<String>();
7206        String[] uidPackages = pm.getPackagesForUid(callingUid);
7207        for (int i = 0; i < uidPackages.length; i++) {
7208            packages.add(uidPackages[i]);
7209        }
7210
7211        synchronized(this) {
7212            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7213            try {
7214                if (localLOGV) Slog.v(TAG, "getAppTasks");
7215
7216                final int N = mRecentTasks.size();
7217                for (int i = 0; i < N; i++) {
7218                    TaskRecord tr = mRecentTasks.get(i);
7219                    // Skip tasks that are not created by the caller
7220                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7221                        ActivityManager.RecentTaskInfo taskInfo =
7222                                createRecentTaskInfoFromTaskRecord(tr);
7223                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7224                        list.add(taskImpl);
7225                    }
7226                }
7227            } finally {
7228                Binder.restoreCallingIdentity(ident);
7229            }
7230            return list;
7231        }
7232    }
7233
7234    @Override
7235    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7236        final int callingUid = Binder.getCallingUid();
7237        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7238
7239        synchronized(this) {
7240            if (localLOGV) Slog.v(
7241                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7242
7243            final boolean allowed = checkCallingPermission(
7244                    android.Manifest.permission.GET_TASKS)
7245                    == PackageManager.PERMISSION_GRANTED;
7246            if (!allowed) {
7247                Slog.w(TAG, "getTasks: caller " + callingUid
7248                        + " does not hold GET_TASKS; limiting output");
7249            }
7250
7251            // TODO: Improve with MRU list from all ActivityStacks.
7252            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7253        }
7254
7255        return list;
7256    }
7257
7258    TaskRecord getMostRecentTask() {
7259        return mRecentTasks.get(0);
7260    }
7261
7262    /**
7263     * Creates a new RecentTaskInfo from a TaskRecord.
7264     */
7265    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7266        // Update the task description to reflect any changes in the task stack
7267        tr.updateTaskDescription();
7268
7269        // Compose the recent task info
7270        ActivityManager.RecentTaskInfo rti
7271                = new ActivityManager.RecentTaskInfo();
7272        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7273        rti.persistentId = tr.taskId;
7274        rti.baseIntent = new Intent(tr.getBaseIntent());
7275        rti.origActivity = tr.origActivity;
7276        rti.description = tr.lastDescription;
7277        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7278        rti.userId = tr.userId;
7279        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7280        rti.firstActiveTime = tr.firstActiveTime;
7281        rti.lastActiveTime = tr.lastActiveTime;
7282        return rti;
7283    }
7284
7285    @Override
7286    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7287            int flags, int userId) {
7288        final int callingUid = Binder.getCallingUid();
7289        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7290                false, true, "getRecentTasks", null);
7291
7292        synchronized (this) {
7293            final boolean allowed = checkCallingPermission(
7294                    android.Manifest.permission.GET_TASKS)
7295                    == PackageManager.PERMISSION_GRANTED;
7296            if (!allowed) {
7297                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7298                        + " does not hold GET_TASKS; limiting output");
7299            }
7300            final boolean detailed = checkCallingPermission(
7301                    android.Manifest.permission.GET_DETAILED_TASKS)
7302                    == PackageManager.PERMISSION_GRANTED;
7303
7304            IPackageManager pm = AppGlobals.getPackageManager();
7305
7306            final int N = mRecentTasks.size();
7307            ArrayList<ActivityManager.RecentTaskInfo> res
7308                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7309                            maxNum < N ? maxNum : N);
7310
7311            final Set<Integer> includedUsers;
7312            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7313                includedUsers = getProfileIdsLocked(userId);
7314            } else {
7315                includedUsers = new HashSet<Integer>();
7316            }
7317            includedUsers.add(Integer.valueOf(userId));
7318            for (int i=0; i<N && maxNum > 0; i++) {
7319                TaskRecord tr = mRecentTasks.get(i);
7320                // Only add calling user or related users recent tasks
7321                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7322
7323                // Return the entry if desired by the caller.  We always return
7324                // the first entry, because callers always expect this to be the
7325                // foreground app.  We may filter others if the caller has
7326                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7327                // we should exclude the entry.
7328
7329                if (i == 0
7330                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7331                        || (tr.intent == null)
7332                        || ((tr.intent.getFlags()
7333                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7334                    if (!allowed) {
7335                        // If the caller doesn't have the GET_TASKS permission, then only
7336                        // allow them to see a small subset of tasks -- their own and home.
7337                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7338                            continue;
7339                        }
7340                    }
7341                    if (tr.intent != null &&
7342                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7343                            != 0 && tr.getTopActivity() == null) {
7344                        // Don't include auto remove tasks that are finished or finishing.
7345                        continue;
7346                    }
7347
7348                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7349                    if (!detailed) {
7350                        rti.baseIntent.replaceExtras((Bundle)null);
7351                    }
7352
7353                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7354                        // Check whether this activity is currently available.
7355                        try {
7356                            if (rti.origActivity != null) {
7357                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7358                                        == null) {
7359                                    continue;
7360                                }
7361                            } else if (rti.baseIntent != null) {
7362                                if (pm.queryIntentActivities(rti.baseIntent,
7363                                        null, 0, userId) == null) {
7364                                    continue;
7365                                }
7366                            }
7367                        } catch (RemoteException e) {
7368                            // Will never happen.
7369                        }
7370                    }
7371
7372                    res.add(rti);
7373                    maxNum--;
7374                }
7375            }
7376            return res;
7377        }
7378    }
7379
7380    private TaskRecord recentTaskForIdLocked(int id) {
7381        final int N = mRecentTasks.size();
7382            for (int i=0; i<N; i++) {
7383                TaskRecord tr = mRecentTasks.get(i);
7384                if (tr.taskId == id) {
7385                    return tr;
7386                }
7387            }
7388            return null;
7389    }
7390
7391    @Override
7392    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7393        synchronized (this) {
7394            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7395                    "getTaskThumbnail()");
7396            TaskRecord tr = recentTaskForIdLocked(id);
7397            if (tr != null) {
7398                return tr.getTaskThumbnailLocked();
7399            }
7400        }
7401        return null;
7402    }
7403
7404    @Override
7405    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7406        synchronized (this) {
7407            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7408            if (r != null) {
7409                r.taskDescription = td;
7410                r.task.updateTaskDescription();
7411            }
7412        }
7413    }
7414
7415    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7416        if (!pr.killedByAm) {
7417            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7418            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7419                    pr.processName, pr.setAdj, reason);
7420            pr.killedByAm = true;
7421            Process.killProcessQuiet(pr.pid);
7422            Process.killProcessGroup(pr.info.uid, pr.pid);
7423        }
7424    }
7425
7426    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7427        tr.disposeThumbnail();
7428        mRecentTasks.remove(tr);
7429        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7430        Intent baseIntent = new Intent(
7431                tr.intent != null ? tr.intent : tr.affinityIntent);
7432        ComponentName component = baseIntent.getComponent();
7433        if (component == null) {
7434            Slog.w(TAG, "Now component for base intent of task: " + tr);
7435            return;
7436        }
7437
7438        // Find any running services associated with this app.
7439        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7440
7441        if (killProcesses) {
7442            // Find any running processes associated with this app.
7443            final String pkg = component.getPackageName();
7444            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7445            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7446            for (int i=0; i<pmap.size(); i++) {
7447                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7448                for (int j=0; j<uids.size(); j++) {
7449                    ProcessRecord proc = uids.valueAt(j);
7450                    if (proc.userId != tr.userId) {
7451                        continue;
7452                    }
7453                    if (!proc.pkgList.containsKey(pkg)) {
7454                        continue;
7455                    }
7456                    procs.add(proc);
7457                }
7458            }
7459
7460            // Kill the running processes.
7461            for (int i=0; i<procs.size(); i++) {
7462                ProcessRecord pr = procs.get(i);
7463                if (pr == mHomeProcess) {
7464                    // Don't kill the home process along with tasks from the same package.
7465                    continue;
7466                }
7467                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7468                    killUnneededProcessLocked(pr, "remove task");
7469                } else {
7470                    pr.waitingToKill = "remove task";
7471                }
7472            }
7473        }
7474    }
7475
7476    /**
7477     * Removes the task with the specified task id.
7478     *
7479     * @param taskId Identifier of the task to be removed.
7480     * @param flags Additional operational flags.  May be 0 or
7481     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7482     * @return Returns true if the given task was found and removed.
7483     */
7484    private boolean removeTaskByIdLocked(int taskId, int flags) {
7485        TaskRecord tr = recentTaskForIdLocked(taskId);
7486        if (tr != null) {
7487            tr.removeTaskActivitiesLocked();
7488            cleanUpRemovedTaskLocked(tr, flags);
7489            if (tr.isPersistable) {
7490                notifyTaskPersisterLocked(tr, true);
7491            }
7492            return true;
7493        }
7494        return false;
7495    }
7496
7497    @Override
7498    public boolean removeTask(int taskId, int flags) {
7499        synchronized (this) {
7500            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7501                    "removeTask()");
7502            long ident = Binder.clearCallingIdentity();
7503            try {
7504                return removeTaskByIdLocked(taskId, flags);
7505            } finally {
7506                Binder.restoreCallingIdentity(ident);
7507            }
7508        }
7509    }
7510
7511    /**
7512     * TODO: Add mController hook
7513     */
7514    @Override
7515    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7516        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7517                "moveTaskToFront()");
7518
7519        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7520        synchronized(this) {
7521            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7522                    Binder.getCallingUid(), "Task to front")) {
7523                ActivityOptions.abort(options);
7524                return;
7525            }
7526            final long origId = Binder.clearCallingIdentity();
7527            try {
7528                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7529                if (task == null) {
7530                    return;
7531                }
7532                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7533                    mStackSupervisor.showLockTaskToast();
7534                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7535                    return;
7536                }
7537                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7538                if (prev != null && prev.isRecentsActivity()) {
7539                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7540                }
7541                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7542            } finally {
7543                Binder.restoreCallingIdentity(origId);
7544            }
7545            ActivityOptions.abort(options);
7546        }
7547    }
7548
7549    @Override
7550    public void moveTaskToBack(int taskId) {
7551        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7552                "moveTaskToBack()");
7553
7554        synchronized(this) {
7555            TaskRecord tr = recentTaskForIdLocked(taskId);
7556            if (tr != null) {
7557                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7558                ActivityStack stack = tr.stack;
7559                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7560                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7561                            Binder.getCallingUid(), "Task to back")) {
7562                        return;
7563                    }
7564                }
7565                final long origId = Binder.clearCallingIdentity();
7566                try {
7567                    stack.moveTaskToBackLocked(taskId, null);
7568                } finally {
7569                    Binder.restoreCallingIdentity(origId);
7570                }
7571            }
7572        }
7573    }
7574
7575    /**
7576     * Moves an activity, and all of the other activities within the same task, to the bottom
7577     * of the history stack.  The activity's order within the task is unchanged.
7578     *
7579     * @param token A reference to the activity we wish to move
7580     * @param nonRoot If false then this only works if the activity is the root
7581     *                of a task; if true it will work for any activity in a task.
7582     * @return Returns true if the move completed, false if not.
7583     */
7584    @Override
7585    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7586        enforceNotIsolatedCaller("moveActivityTaskToBack");
7587        synchronized(this) {
7588            final long origId = Binder.clearCallingIdentity();
7589            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7590            if (taskId >= 0) {
7591                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7592            }
7593            Binder.restoreCallingIdentity(origId);
7594        }
7595        return false;
7596    }
7597
7598    @Override
7599    public void moveTaskBackwards(int task) {
7600        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7601                "moveTaskBackwards()");
7602
7603        synchronized(this) {
7604            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7605                    Binder.getCallingUid(), "Task backwards")) {
7606                return;
7607            }
7608            final long origId = Binder.clearCallingIdentity();
7609            moveTaskBackwardsLocked(task);
7610            Binder.restoreCallingIdentity(origId);
7611        }
7612    }
7613
7614    private final void moveTaskBackwardsLocked(int task) {
7615        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7616    }
7617
7618    @Override
7619    public IBinder getHomeActivityToken() throws RemoteException {
7620        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7621                "getHomeActivityToken()");
7622        synchronized (this) {
7623            return mStackSupervisor.getHomeActivityToken();
7624        }
7625    }
7626
7627    @Override
7628    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7629            IActivityContainerCallback callback) throws RemoteException {
7630        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7631                "createActivityContainer()");
7632        synchronized (this) {
7633            if (parentActivityToken == null) {
7634                throw new IllegalArgumentException("parent token must not be null");
7635            }
7636            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7637            if (r == null) {
7638                return null;
7639            }
7640            if (callback == null) {
7641                throw new IllegalArgumentException("callback must not be null");
7642            }
7643            return mStackSupervisor.createActivityContainer(r, callback);
7644        }
7645    }
7646
7647    @Override
7648    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7649        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7650                "deleteActivityContainer()");
7651        synchronized (this) {
7652            mStackSupervisor.deleteActivityContainer(container);
7653        }
7654    }
7655
7656    @Override
7657    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7658            throws RemoteException {
7659        synchronized (this) {
7660            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7661            if (stack != null) {
7662                return stack.mActivityContainer;
7663            }
7664            return null;
7665        }
7666    }
7667
7668    @Override
7669    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7670        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7671                "moveTaskToStack()");
7672        if (stackId == HOME_STACK_ID) {
7673            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7674                    new RuntimeException("here").fillInStackTrace());
7675        }
7676        synchronized (this) {
7677            long ident = Binder.clearCallingIdentity();
7678            try {
7679                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7680                        + stackId + " toTop=" + toTop);
7681                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7682            } finally {
7683                Binder.restoreCallingIdentity(ident);
7684            }
7685        }
7686    }
7687
7688    @Override
7689    public void resizeStack(int stackBoxId, Rect bounds) {
7690        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7691                "resizeStackBox()");
7692        long ident = Binder.clearCallingIdentity();
7693        try {
7694            mWindowManager.resizeStack(stackBoxId, bounds);
7695        } finally {
7696            Binder.restoreCallingIdentity(ident);
7697        }
7698    }
7699
7700    @Override
7701    public List<StackInfo> getAllStackInfos() {
7702        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7703                "getAllStackInfos()");
7704        long ident = Binder.clearCallingIdentity();
7705        try {
7706            synchronized (this) {
7707                return mStackSupervisor.getAllStackInfosLocked();
7708            }
7709        } finally {
7710            Binder.restoreCallingIdentity(ident);
7711        }
7712    }
7713
7714    @Override
7715    public StackInfo getStackInfo(int stackId) {
7716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7717                "getStackInfo()");
7718        long ident = Binder.clearCallingIdentity();
7719        try {
7720            synchronized (this) {
7721                return mStackSupervisor.getStackInfoLocked(stackId);
7722            }
7723        } finally {
7724            Binder.restoreCallingIdentity(ident);
7725        }
7726    }
7727
7728    @Override
7729    public boolean isInHomeStack(int taskId) {
7730        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7731                "getStackInfo()");
7732        long ident = Binder.clearCallingIdentity();
7733        try {
7734            synchronized (this) {
7735                TaskRecord tr = recentTaskForIdLocked(taskId);
7736                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7737            }
7738        } finally {
7739            Binder.restoreCallingIdentity(ident);
7740        }
7741    }
7742
7743    @Override
7744    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7745        synchronized(this) {
7746            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7747        }
7748    }
7749
7750    private boolean isLockTaskAuthorized(String pkg) {
7751        final DevicePolicyManager dpm = (DevicePolicyManager)
7752                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7753        try {
7754            int uid = mContext.getPackageManager().getPackageUid(pkg,
7755                    Binder.getCallingUserHandle().getIdentifier());
7756            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7757        } catch (NameNotFoundException e) {
7758            return false;
7759        }
7760    }
7761
7762    void startLockTaskMode(TaskRecord task) {
7763        final String pkg;
7764        synchronized (this) {
7765            pkg = task.intent.getComponent().getPackageName();
7766        }
7767        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7768        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7769            final TaskRecord taskRecord = task;
7770            mHandler.post(new Runnable() {
7771                @Override
7772                public void run() {
7773                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7774                }
7775            });
7776            return;
7777        }
7778        long ident = Binder.clearCallingIdentity();
7779        try {
7780            synchronized (this) {
7781                // Since we lost lock on task, make sure it is still there.
7782                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7783                if (task != null) {
7784                    if (!isSystemInitiated
7785                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7786                        throw new IllegalArgumentException("Invalid task, not in foreground");
7787                    }
7788                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7789                }
7790            }
7791        } finally {
7792            Binder.restoreCallingIdentity(ident);
7793        }
7794    }
7795
7796    @Override
7797    public void startLockTaskMode(int taskId) {
7798        final TaskRecord task;
7799        long ident = Binder.clearCallingIdentity();
7800        try {
7801            synchronized (this) {
7802                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7803            }
7804        } finally {
7805            Binder.restoreCallingIdentity(ident);
7806        }
7807        if (task != null) {
7808            startLockTaskMode(task);
7809        }
7810    }
7811
7812    @Override
7813    public void startLockTaskMode(IBinder token) {
7814        final TaskRecord task;
7815        long ident = Binder.clearCallingIdentity();
7816        try {
7817            synchronized (this) {
7818                final ActivityRecord r = ActivityRecord.forToken(token);
7819                if (r == null) {
7820                    return;
7821                }
7822                task = r.task;
7823            }
7824        } finally {
7825            Binder.restoreCallingIdentity(ident);
7826        }
7827        if (task != null) {
7828            startLockTaskMode(task);
7829        }
7830    }
7831
7832    @Override
7833    public void startLockTaskModeOnCurrent() throws RemoteException {
7834        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7835        ActivityRecord r = null;
7836        synchronized (this) {
7837            r = mStackSupervisor.topRunningActivityLocked();
7838        }
7839        startLockTaskMode(r.task);
7840    }
7841
7842    @Override
7843    public void stopLockTaskMode() {
7844        // Verify that the user matches the package of the intent for the TaskRecord
7845        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7846        // and stopLockTaskMode.
7847        final int callingUid = Binder.getCallingUid();
7848        if (callingUid != Process.SYSTEM_UID) {
7849            try {
7850                String pkg =
7851                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7852                int uid = mContext.getPackageManager().getPackageUid(pkg,
7853                        Binder.getCallingUserHandle().getIdentifier());
7854                if (uid != callingUid) {
7855                    throw new SecurityException("Invalid uid, expected " + uid);
7856                }
7857            } catch (NameNotFoundException e) {
7858                Log.d(TAG, "stopLockTaskMode " + e);
7859                return;
7860            }
7861        }
7862        long ident = Binder.clearCallingIdentity();
7863        try {
7864            Log.d(TAG, "stopLockTaskMode");
7865            // Stop lock task
7866            synchronized (this) {
7867                mStackSupervisor.setLockTaskModeLocked(null, false);
7868            }
7869        } finally {
7870            Binder.restoreCallingIdentity(ident);
7871        }
7872    }
7873
7874    @Override
7875    public void stopLockTaskModeOnCurrent() throws RemoteException {
7876        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7877        long ident = Binder.clearCallingIdentity();
7878        try {
7879            stopLockTaskMode();
7880        } finally {
7881            Binder.restoreCallingIdentity(ident);
7882        }
7883    }
7884
7885    @Override
7886    public boolean isInLockTaskMode() {
7887        synchronized (this) {
7888            return mStackSupervisor.isInLockTaskMode();
7889        }
7890    }
7891
7892    // =========================================================
7893    // CONTENT PROVIDERS
7894    // =========================================================
7895
7896    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7897        List<ProviderInfo> providers = null;
7898        try {
7899            providers = AppGlobals.getPackageManager().
7900                queryContentProviders(app.processName, app.uid,
7901                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7902        } catch (RemoteException ex) {
7903        }
7904        if (DEBUG_MU)
7905            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7906        int userId = app.userId;
7907        if (providers != null) {
7908            int N = providers.size();
7909            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7910            for (int i=0; i<N; i++) {
7911                ProviderInfo cpi =
7912                    (ProviderInfo)providers.get(i);
7913                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7914                        cpi.name, cpi.flags);
7915                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7916                    // This is a singleton provider, but a user besides the
7917                    // default user is asking to initialize a process it runs
7918                    // in...  well, no, it doesn't actually run in this process,
7919                    // it runs in the process of the default user.  Get rid of it.
7920                    providers.remove(i);
7921                    N--;
7922                    i--;
7923                    continue;
7924                }
7925
7926                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7927                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7928                if (cpr == null) {
7929                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7930                    mProviderMap.putProviderByClass(comp, cpr);
7931                }
7932                if (DEBUG_MU)
7933                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7934                app.pubProviders.put(cpi.name, cpr);
7935                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7936                    // Don't add this if it is a platform component that is marked
7937                    // to run in multiple processes, because this is actually
7938                    // part of the framework so doesn't make sense to track as a
7939                    // separate apk in the process.
7940                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7941                            mProcessStats);
7942                }
7943                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7944            }
7945        }
7946        return providers;
7947    }
7948
7949    /**
7950     * Check if {@link ProcessRecord} has a possible chance at accessing the
7951     * given {@link ProviderInfo}. Final permission checking is always done
7952     * in {@link ContentProvider}.
7953     */
7954    private final String checkContentProviderPermissionLocked(
7955            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7956        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7957        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7958        boolean checkedGrants = false;
7959        if (checkUser) {
7960            // Looking for cross-user grants before enforcing the typical cross-users permissions
7961            if (UserHandle.getUserId(callingUid) != userId) {
7962                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7963                    return null;
7964                }
7965                checkedGrants = true;
7966            }
7967            userId = handleIncomingUser(callingPid, callingUid, userId,
7968                    false, false, "checkContentProviderPermissionLocked " + cpi.authority, null);
7969        }
7970        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7971                cpi.applicationInfo.uid, cpi.exported)
7972                == PackageManager.PERMISSION_GRANTED) {
7973            return null;
7974        }
7975        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7976                cpi.applicationInfo.uid, cpi.exported)
7977                == PackageManager.PERMISSION_GRANTED) {
7978            return null;
7979        }
7980
7981        PathPermission[] pps = cpi.pathPermissions;
7982        if (pps != null) {
7983            int i = pps.length;
7984            while (i > 0) {
7985                i--;
7986                PathPermission pp = pps[i];
7987                String pprperm = pp.getReadPermission();
7988                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
7989                        cpi.applicationInfo.uid, cpi.exported)
7990                        == PackageManager.PERMISSION_GRANTED) {
7991                    return null;
7992                }
7993                String ppwperm = pp.getWritePermission();
7994                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
7995                        cpi.applicationInfo.uid, cpi.exported)
7996                        == PackageManager.PERMISSION_GRANTED) {
7997                    return null;
7998                }
7999            }
8000        }
8001        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8002            return null;
8003        }
8004
8005        String msg;
8006        if (!cpi.exported) {
8007            msg = "Permission Denial: opening provider " + cpi.name
8008                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8009                    + ", uid=" + callingUid + ") that is not exported from uid "
8010                    + cpi.applicationInfo.uid;
8011        } else {
8012            msg = "Permission Denial: opening provider " + cpi.name
8013                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8014                    + ", uid=" + callingUid + ") requires "
8015                    + cpi.readPermission + " or " + cpi.writePermission;
8016        }
8017        Slog.w(TAG, msg);
8018        return msg;
8019    }
8020
8021    /**
8022     * Returns if the ContentProvider has granted a uri to callingUid
8023     */
8024    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8025        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8026        if (perms != null) {
8027            for (GrantUri grantUri : perms.keySet()) {
8028                if (grantUri.sourceUserId == userId || !checkUser) {
8029                    if (matchesProvider(grantUri.uri, cpi)) {
8030                        return true;
8031                    }
8032                }
8033            }
8034        }
8035        return false;
8036    }
8037
8038    /**
8039     * Returns true if the uri authority is one of the authorities specified in the provider.
8040     */
8041    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8042        String uriAuth = uri.getAuthority();
8043        String cpiAuth = cpi.authority;
8044        if (cpiAuth.indexOf(';') == -1) {
8045            return cpiAuth.equals(uriAuth);
8046        }
8047        String[] cpiAuths = cpiAuth.split(";");
8048        int length = cpiAuths.length;
8049        for (int i = 0; i < length; i++) {
8050            if (cpiAuths[i].equals(uriAuth)) return true;
8051        }
8052        return false;
8053    }
8054
8055    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8056            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8057        if (r != null) {
8058            for (int i=0; i<r.conProviders.size(); i++) {
8059                ContentProviderConnection conn = r.conProviders.get(i);
8060                if (conn.provider == cpr) {
8061                    if (DEBUG_PROVIDER) Slog.v(TAG,
8062                            "Adding provider requested by "
8063                            + r.processName + " from process "
8064                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8065                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8066                    if (stable) {
8067                        conn.stableCount++;
8068                        conn.numStableIncs++;
8069                    } else {
8070                        conn.unstableCount++;
8071                        conn.numUnstableIncs++;
8072                    }
8073                    return conn;
8074                }
8075            }
8076            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8077            if (stable) {
8078                conn.stableCount = 1;
8079                conn.numStableIncs = 1;
8080            } else {
8081                conn.unstableCount = 1;
8082                conn.numUnstableIncs = 1;
8083            }
8084            cpr.connections.add(conn);
8085            r.conProviders.add(conn);
8086            return conn;
8087        }
8088        cpr.addExternalProcessHandleLocked(externalProcessToken);
8089        return null;
8090    }
8091
8092    boolean decProviderCountLocked(ContentProviderConnection conn,
8093            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8094        if (conn != null) {
8095            cpr = conn.provider;
8096            if (DEBUG_PROVIDER) Slog.v(TAG,
8097                    "Removing provider requested by "
8098                    + conn.client.processName + " from process "
8099                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8100                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8101            if (stable) {
8102                conn.stableCount--;
8103            } else {
8104                conn.unstableCount--;
8105            }
8106            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8107                cpr.connections.remove(conn);
8108                conn.client.conProviders.remove(conn);
8109                return true;
8110            }
8111            return false;
8112        }
8113        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8114        return false;
8115    }
8116
8117    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8118            String name, IBinder token, boolean stable, int userId) {
8119        ContentProviderRecord cpr;
8120        ContentProviderConnection conn = null;
8121        ProviderInfo cpi = null;
8122
8123        synchronized(this) {
8124            ProcessRecord r = null;
8125            if (caller != null) {
8126                r = getRecordForAppLocked(caller);
8127                if (r == null) {
8128                    throw new SecurityException(
8129                            "Unable to find app for caller " + caller
8130                          + " (pid=" + Binder.getCallingPid()
8131                          + ") when getting content provider " + name);
8132                }
8133            }
8134
8135            boolean checkCrossUser = true;
8136
8137            // First check if this content provider has been published...
8138            cpr = mProviderMap.getProviderByName(name, userId);
8139            // If that didn't work, check if it exists for user 0 and then
8140            // verify that it's a singleton provider before using it.
8141            if (cpr == null && userId != UserHandle.USER_OWNER) {
8142                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8143                if (cpr != null) {
8144                    cpi = cpr.info;
8145                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8146                            cpi.name, cpi.flags)
8147                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8148                        userId = UserHandle.USER_OWNER;
8149                        checkCrossUser = false;
8150                    } else {
8151                        cpr = null;
8152                        cpi = null;
8153                    }
8154                }
8155            }
8156
8157            boolean providerRunning = cpr != null;
8158            if (providerRunning) {
8159                cpi = cpr.info;
8160                String msg;
8161                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8162                        != null) {
8163                    throw new SecurityException(msg);
8164                }
8165
8166                if (r != null && cpr.canRunHere(r)) {
8167                    // This provider has been published or is in the process
8168                    // of being published...  but it is also allowed to run
8169                    // in the caller's process, so don't make a connection
8170                    // and just let the caller instantiate its own instance.
8171                    ContentProviderHolder holder = cpr.newHolder(null);
8172                    // don't give caller the provider object, it needs
8173                    // to make its own.
8174                    holder.provider = null;
8175                    return holder;
8176                }
8177
8178                final long origId = Binder.clearCallingIdentity();
8179
8180                // In this case the provider instance already exists, so we can
8181                // return it right away.
8182                conn = incProviderCountLocked(r, cpr, token, stable);
8183                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8184                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8185                        // If this is a perceptible app accessing the provider,
8186                        // make sure to count it as being accessed and thus
8187                        // back up on the LRU list.  This is good because
8188                        // content providers are often expensive to start.
8189                        updateLruProcessLocked(cpr.proc, false, null);
8190                    }
8191                }
8192
8193                if (cpr.proc != null) {
8194                    if (false) {
8195                        if (cpr.name.flattenToShortString().equals(
8196                                "com.android.providers.calendar/.CalendarProvider2")) {
8197                            Slog.v(TAG, "****************** KILLING "
8198                                + cpr.name.flattenToShortString());
8199                            Process.killProcess(cpr.proc.pid);
8200                        }
8201                    }
8202                    boolean success = updateOomAdjLocked(cpr.proc);
8203                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8204                    // NOTE: there is still a race here where a signal could be
8205                    // pending on the process even though we managed to update its
8206                    // adj level.  Not sure what to do about this, but at least
8207                    // the race is now smaller.
8208                    if (!success) {
8209                        // Uh oh...  it looks like the provider's process
8210                        // has been killed on us.  We need to wait for a new
8211                        // process to be started, and make sure its death
8212                        // doesn't kill our process.
8213                        Slog.i(TAG,
8214                                "Existing provider " + cpr.name.flattenToShortString()
8215                                + " is crashing; detaching " + r);
8216                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8217                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8218                        if (!lastRef) {
8219                            // This wasn't the last ref our process had on
8220                            // the provider...  we have now been killed, bail.
8221                            return null;
8222                        }
8223                        providerRunning = false;
8224                        conn = null;
8225                    }
8226                }
8227
8228                Binder.restoreCallingIdentity(origId);
8229            }
8230
8231            boolean singleton;
8232            if (!providerRunning) {
8233                try {
8234                    cpi = AppGlobals.getPackageManager().
8235                        resolveContentProvider(name,
8236                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8237                } catch (RemoteException ex) {
8238                }
8239                if (cpi == null) {
8240                    return null;
8241                }
8242                // If the provider is a singleton AND
8243                // (it's a call within the same user || the provider is a
8244                // privileged app)
8245                // Then allow connecting to the singleton provider
8246                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8247                        cpi.name, cpi.flags)
8248                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8249                if (singleton) {
8250                    userId = UserHandle.USER_OWNER;
8251                }
8252                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8253
8254                String msg;
8255                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8256                        != null) {
8257                    throw new SecurityException(msg);
8258                }
8259
8260                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8261                        && !cpi.processName.equals("system")) {
8262                    // If this content provider does not run in the system
8263                    // process, and the system is not yet ready to run other
8264                    // processes, then fail fast instead of hanging.
8265                    throw new IllegalArgumentException(
8266                            "Attempt to launch content provider before system ready");
8267                }
8268
8269                // Make sure that the user who owns this provider is started.  If not,
8270                // we don't want to allow it to run.
8271                if (mStartedUsers.get(userId) == null) {
8272                    Slog.w(TAG, "Unable to launch app "
8273                            + cpi.applicationInfo.packageName + "/"
8274                            + cpi.applicationInfo.uid + " for provider "
8275                            + name + ": user " + userId + " is stopped");
8276                    return null;
8277                }
8278
8279                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8280                cpr = mProviderMap.getProviderByClass(comp, userId);
8281                final boolean firstClass = cpr == null;
8282                if (firstClass) {
8283                    try {
8284                        ApplicationInfo ai =
8285                            AppGlobals.getPackageManager().
8286                                getApplicationInfo(
8287                                        cpi.applicationInfo.packageName,
8288                                        STOCK_PM_FLAGS, userId);
8289                        if (ai == null) {
8290                            Slog.w(TAG, "No package info for content provider "
8291                                    + cpi.name);
8292                            return null;
8293                        }
8294                        ai = getAppInfoForUser(ai, userId);
8295                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8296                    } catch (RemoteException ex) {
8297                        // pm is in same process, this will never happen.
8298                    }
8299                }
8300
8301                if (r != null && cpr.canRunHere(r)) {
8302                    // If this is a multiprocess provider, then just return its
8303                    // info and allow the caller to instantiate it.  Only do
8304                    // this if the provider is the same user as the caller's
8305                    // process, or can run as root (so can be in any process).
8306                    return cpr.newHolder(null);
8307                }
8308
8309                if (DEBUG_PROVIDER) {
8310                    RuntimeException e = new RuntimeException("here");
8311                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8312                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8313                }
8314
8315                // This is single process, and our app is now connecting to it.
8316                // See if we are already in the process of launching this
8317                // provider.
8318                final int N = mLaunchingProviders.size();
8319                int i;
8320                for (i=0; i<N; i++) {
8321                    if (mLaunchingProviders.get(i) == cpr) {
8322                        break;
8323                    }
8324                }
8325
8326                // If the provider is not already being launched, then get it
8327                // started.
8328                if (i >= N) {
8329                    final long origId = Binder.clearCallingIdentity();
8330
8331                    try {
8332                        // Content provider is now in use, its package can't be stopped.
8333                        try {
8334                            AppGlobals.getPackageManager().setPackageStoppedState(
8335                                    cpr.appInfo.packageName, false, userId);
8336                        } catch (RemoteException e) {
8337                        } catch (IllegalArgumentException e) {
8338                            Slog.w(TAG, "Failed trying to unstop package "
8339                                    + cpr.appInfo.packageName + ": " + e);
8340                        }
8341
8342                        // Use existing process if already started
8343                        ProcessRecord proc = getProcessRecordLocked(
8344                                cpi.processName, cpr.appInfo.uid, false);
8345                        if (proc != null && proc.thread != null) {
8346                            if (DEBUG_PROVIDER) {
8347                                Slog.d(TAG, "Installing in existing process " + proc);
8348                            }
8349                            proc.pubProviders.put(cpi.name, cpr);
8350                            try {
8351                                proc.thread.scheduleInstallProvider(cpi);
8352                            } catch (RemoteException e) {
8353                            }
8354                        } else {
8355                            proc = startProcessLocked(cpi.processName,
8356                                    cpr.appInfo, false, 0, "content provider",
8357                                    new ComponentName(cpi.applicationInfo.packageName,
8358                                            cpi.name), false, false, false);
8359                            if (proc == null) {
8360                                Slog.w(TAG, "Unable to launch app "
8361                                        + cpi.applicationInfo.packageName + "/"
8362                                        + cpi.applicationInfo.uid + " for provider "
8363                                        + name + ": process is bad");
8364                                return null;
8365                            }
8366                        }
8367                        cpr.launchingApp = proc;
8368                        mLaunchingProviders.add(cpr);
8369                    } finally {
8370                        Binder.restoreCallingIdentity(origId);
8371                    }
8372                }
8373
8374                // Make sure the provider is published (the same provider class
8375                // may be published under multiple names).
8376                if (firstClass) {
8377                    mProviderMap.putProviderByClass(comp, cpr);
8378                }
8379
8380                mProviderMap.putProviderByName(name, cpr);
8381                conn = incProviderCountLocked(r, cpr, token, stable);
8382                if (conn != null) {
8383                    conn.waiting = true;
8384                }
8385            }
8386        }
8387
8388        // Wait for the provider to be published...
8389        synchronized (cpr) {
8390            while (cpr.provider == null) {
8391                if (cpr.launchingApp == null) {
8392                    Slog.w(TAG, "Unable to launch app "
8393                            + cpi.applicationInfo.packageName + "/"
8394                            + cpi.applicationInfo.uid + " for provider "
8395                            + name + ": launching app became null");
8396                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8397                            UserHandle.getUserId(cpi.applicationInfo.uid),
8398                            cpi.applicationInfo.packageName,
8399                            cpi.applicationInfo.uid, name);
8400                    return null;
8401                }
8402                try {
8403                    if (DEBUG_MU) {
8404                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8405                                + cpr.launchingApp);
8406                    }
8407                    if (conn != null) {
8408                        conn.waiting = true;
8409                    }
8410                    cpr.wait();
8411                } catch (InterruptedException ex) {
8412                } finally {
8413                    if (conn != null) {
8414                        conn.waiting = false;
8415                    }
8416                }
8417            }
8418        }
8419        return cpr != null ? cpr.newHolder(conn) : null;
8420    }
8421
8422    @Override
8423    public final ContentProviderHolder getContentProvider(
8424            IApplicationThread caller, String name, int userId, boolean stable) {
8425        enforceNotIsolatedCaller("getContentProvider");
8426        if (caller == null) {
8427            String msg = "null IApplicationThread when getting content provider "
8428                    + name;
8429            Slog.w(TAG, msg);
8430            throw new SecurityException(msg);
8431        }
8432        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8433        // with cross-user grant.
8434        return getContentProviderImpl(caller, name, null, stable, userId);
8435    }
8436
8437    public ContentProviderHolder getContentProviderExternal(
8438            String name, int userId, IBinder token) {
8439        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8440            "Do not have permission in call getContentProviderExternal()");
8441        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8442                false, true, "getContentProvider", null);
8443        return getContentProviderExternalUnchecked(name, token, userId);
8444    }
8445
8446    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8447            IBinder token, int userId) {
8448        return getContentProviderImpl(null, name, token, true, userId);
8449    }
8450
8451    /**
8452     * Drop a content provider from a ProcessRecord's bookkeeping
8453     */
8454    public void removeContentProvider(IBinder connection, boolean stable) {
8455        enforceNotIsolatedCaller("removeContentProvider");
8456        long ident = Binder.clearCallingIdentity();
8457        try {
8458            synchronized (this) {
8459                ContentProviderConnection conn;
8460                try {
8461                    conn = (ContentProviderConnection)connection;
8462                } catch (ClassCastException e) {
8463                    String msg ="removeContentProvider: " + connection
8464                            + " not a ContentProviderConnection";
8465                    Slog.w(TAG, msg);
8466                    throw new IllegalArgumentException(msg);
8467                }
8468                if (conn == null) {
8469                    throw new NullPointerException("connection is null");
8470                }
8471                if (decProviderCountLocked(conn, null, null, stable)) {
8472                    updateOomAdjLocked();
8473                }
8474            }
8475        } finally {
8476            Binder.restoreCallingIdentity(ident);
8477        }
8478    }
8479
8480    public void removeContentProviderExternal(String name, IBinder token) {
8481        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8482            "Do not have permission in call removeContentProviderExternal()");
8483        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8484    }
8485
8486    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8487        synchronized (this) {
8488            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8489            if(cpr == null) {
8490                //remove from mProvidersByClass
8491                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8492                return;
8493            }
8494
8495            //update content provider record entry info
8496            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8497            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8498            if (localCpr.hasExternalProcessHandles()) {
8499                if (localCpr.removeExternalProcessHandleLocked(token)) {
8500                    updateOomAdjLocked();
8501                } else {
8502                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8503                            + " with no external reference for token: "
8504                            + token + ".");
8505                }
8506            } else {
8507                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8508                        + " with no external references.");
8509            }
8510        }
8511    }
8512
8513    public final void publishContentProviders(IApplicationThread caller,
8514            List<ContentProviderHolder> providers) {
8515        if (providers == null) {
8516            return;
8517        }
8518
8519        enforceNotIsolatedCaller("publishContentProviders");
8520        synchronized (this) {
8521            final ProcessRecord r = getRecordForAppLocked(caller);
8522            if (DEBUG_MU)
8523                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8524            if (r == null) {
8525                throw new SecurityException(
8526                        "Unable to find app for caller " + caller
8527                      + " (pid=" + Binder.getCallingPid()
8528                      + ") when publishing content providers");
8529            }
8530
8531            final long origId = Binder.clearCallingIdentity();
8532
8533            final int N = providers.size();
8534            for (int i=0; i<N; i++) {
8535                ContentProviderHolder src = providers.get(i);
8536                if (src == null || src.info == null || src.provider == null) {
8537                    continue;
8538                }
8539                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8540                if (DEBUG_MU)
8541                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8542                if (dst != null) {
8543                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8544                    mProviderMap.putProviderByClass(comp, dst);
8545                    String names[] = dst.info.authority.split(";");
8546                    for (int j = 0; j < names.length; j++) {
8547                        mProviderMap.putProviderByName(names[j], dst);
8548                    }
8549
8550                    int NL = mLaunchingProviders.size();
8551                    int j;
8552                    for (j=0; j<NL; j++) {
8553                        if (mLaunchingProviders.get(j) == dst) {
8554                            mLaunchingProviders.remove(j);
8555                            j--;
8556                            NL--;
8557                        }
8558                    }
8559                    synchronized (dst) {
8560                        dst.provider = src.provider;
8561                        dst.proc = r;
8562                        dst.notifyAll();
8563                    }
8564                    updateOomAdjLocked(r);
8565                }
8566            }
8567
8568            Binder.restoreCallingIdentity(origId);
8569        }
8570    }
8571
8572    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8573        ContentProviderConnection conn;
8574        try {
8575            conn = (ContentProviderConnection)connection;
8576        } catch (ClassCastException e) {
8577            String msg ="refContentProvider: " + connection
8578                    + " not a ContentProviderConnection";
8579            Slog.w(TAG, msg);
8580            throw new IllegalArgumentException(msg);
8581        }
8582        if (conn == null) {
8583            throw new NullPointerException("connection is null");
8584        }
8585
8586        synchronized (this) {
8587            if (stable > 0) {
8588                conn.numStableIncs += stable;
8589            }
8590            stable = conn.stableCount + stable;
8591            if (stable < 0) {
8592                throw new IllegalStateException("stableCount < 0: " + stable);
8593            }
8594
8595            if (unstable > 0) {
8596                conn.numUnstableIncs += unstable;
8597            }
8598            unstable = conn.unstableCount + unstable;
8599            if (unstable < 0) {
8600                throw new IllegalStateException("unstableCount < 0: " + unstable);
8601            }
8602
8603            if ((stable+unstable) <= 0) {
8604                throw new IllegalStateException("ref counts can't go to zero here: stable="
8605                        + stable + " unstable=" + unstable);
8606            }
8607            conn.stableCount = stable;
8608            conn.unstableCount = unstable;
8609            return !conn.dead;
8610        }
8611    }
8612
8613    public void unstableProviderDied(IBinder connection) {
8614        ContentProviderConnection conn;
8615        try {
8616            conn = (ContentProviderConnection)connection;
8617        } catch (ClassCastException e) {
8618            String msg ="refContentProvider: " + connection
8619                    + " not a ContentProviderConnection";
8620            Slog.w(TAG, msg);
8621            throw new IllegalArgumentException(msg);
8622        }
8623        if (conn == null) {
8624            throw new NullPointerException("connection is null");
8625        }
8626
8627        // Safely retrieve the content provider associated with the connection.
8628        IContentProvider provider;
8629        synchronized (this) {
8630            provider = conn.provider.provider;
8631        }
8632
8633        if (provider == null) {
8634            // Um, yeah, we're way ahead of you.
8635            return;
8636        }
8637
8638        // Make sure the caller is being honest with us.
8639        if (provider.asBinder().pingBinder()) {
8640            // Er, no, still looks good to us.
8641            synchronized (this) {
8642                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8643                        + " says " + conn + " died, but we don't agree");
8644                return;
8645            }
8646        }
8647
8648        // Well look at that!  It's dead!
8649        synchronized (this) {
8650            if (conn.provider.provider != provider) {
8651                // But something changed...  good enough.
8652                return;
8653            }
8654
8655            ProcessRecord proc = conn.provider.proc;
8656            if (proc == null || proc.thread == null) {
8657                // Seems like the process is already cleaned up.
8658                return;
8659            }
8660
8661            // As far as we're concerned, this is just like receiving a
8662            // death notification...  just a bit prematurely.
8663            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8664                    + ") early provider death");
8665            final long ident = Binder.clearCallingIdentity();
8666            try {
8667                appDiedLocked(proc, proc.pid, proc.thread);
8668            } finally {
8669                Binder.restoreCallingIdentity(ident);
8670            }
8671        }
8672    }
8673
8674    @Override
8675    public void appNotRespondingViaProvider(IBinder connection) {
8676        enforceCallingPermission(
8677                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8678
8679        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8680        if (conn == null) {
8681            Slog.w(TAG, "ContentProviderConnection is null");
8682            return;
8683        }
8684
8685        final ProcessRecord host = conn.provider.proc;
8686        if (host == null) {
8687            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8688            return;
8689        }
8690
8691        final long token = Binder.clearCallingIdentity();
8692        try {
8693            appNotResponding(host, null, null, false, "ContentProvider not responding");
8694        } finally {
8695            Binder.restoreCallingIdentity(token);
8696        }
8697    }
8698
8699    public final void installSystemProviders() {
8700        List<ProviderInfo> providers;
8701        synchronized (this) {
8702            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8703            providers = generateApplicationProvidersLocked(app);
8704            if (providers != null) {
8705                for (int i=providers.size()-1; i>=0; i--) {
8706                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8707                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8708                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8709                                + ": not system .apk");
8710                        providers.remove(i);
8711                    }
8712                }
8713            }
8714        }
8715        if (providers != null) {
8716            mSystemThread.installSystemProviders(providers);
8717        }
8718
8719        mCoreSettingsObserver = new CoreSettingsObserver(this);
8720
8721        mUsageStatsService.monitorPackages();
8722    }
8723
8724    /**
8725     * Allows app to retrieve the MIME type of a URI without having permission
8726     * to access its content provider.
8727     *
8728     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8729     *
8730     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8731     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8732     */
8733    public String getProviderMimeType(Uri uri, int userId) {
8734        enforceNotIsolatedCaller("getProviderMimeType");
8735        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8736                userId, false, true, "getProviderMimeType", null);
8737        final String name = uri.getAuthority();
8738        final long ident = Binder.clearCallingIdentity();
8739        ContentProviderHolder holder = null;
8740
8741        try {
8742            holder = getContentProviderExternalUnchecked(name, null, userId);
8743            if (holder != null) {
8744                return holder.provider.getType(uri);
8745            }
8746        } catch (RemoteException e) {
8747            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8748            return null;
8749        } finally {
8750            if (holder != null) {
8751                removeContentProviderExternalUnchecked(name, null, userId);
8752            }
8753            Binder.restoreCallingIdentity(ident);
8754        }
8755
8756        return null;
8757    }
8758
8759    // =========================================================
8760    // GLOBAL MANAGEMENT
8761    // =========================================================
8762
8763    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8764            boolean isolated) {
8765        String proc = customProcess != null ? customProcess : info.processName;
8766        BatteryStatsImpl.Uid.Proc ps = null;
8767        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8768        int uid = info.uid;
8769        if (isolated) {
8770            int userId = UserHandle.getUserId(uid);
8771            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8772            while (true) {
8773                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8774                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8775                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8776                }
8777                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8778                mNextIsolatedProcessUid++;
8779                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8780                    // No process for this uid, use it.
8781                    break;
8782                }
8783                stepsLeft--;
8784                if (stepsLeft <= 0) {
8785                    return null;
8786                }
8787            }
8788        }
8789        return new ProcessRecord(stats, info, proc, uid);
8790    }
8791
8792    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8793            String abiOverride) {
8794        ProcessRecord app;
8795        if (!isolated) {
8796            app = getProcessRecordLocked(info.processName, info.uid, true);
8797        } else {
8798            app = null;
8799        }
8800
8801        if (app == null) {
8802            app = newProcessRecordLocked(info, null, isolated);
8803            mProcessNames.put(info.processName, app.uid, app);
8804            if (isolated) {
8805                mIsolatedProcesses.put(app.uid, app);
8806            }
8807            updateLruProcessLocked(app, false, null);
8808            updateOomAdjLocked();
8809        }
8810
8811        // This package really, really can not be stopped.
8812        try {
8813            AppGlobals.getPackageManager().setPackageStoppedState(
8814                    info.packageName, false, UserHandle.getUserId(app.uid));
8815        } catch (RemoteException e) {
8816        } catch (IllegalArgumentException e) {
8817            Slog.w(TAG, "Failed trying to unstop package "
8818                    + info.packageName + ": " + e);
8819        }
8820
8821        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8822                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8823            app.persistent = true;
8824            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8825        }
8826        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8827            mPersistentStartingProcesses.add(app);
8828            startProcessLocked(app, "added application", app.processName,
8829                    abiOverride);
8830        }
8831
8832        return app;
8833    }
8834
8835    public void unhandledBack() {
8836        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8837                "unhandledBack()");
8838
8839        synchronized(this) {
8840            final long origId = Binder.clearCallingIdentity();
8841            try {
8842                getFocusedStack().unhandledBackLocked();
8843            } finally {
8844                Binder.restoreCallingIdentity(origId);
8845            }
8846        }
8847    }
8848
8849    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8850        enforceNotIsolatedCaller("openContentUri");
8851        final int userId = UserHandle.getCallingUserId();
8852        String name = uri.getAuthority();
8853        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8854        ParcelFileDescriptor pfd = null;
8855        if (cph != null) {
8856            // We record the binder invoker's uid in thread-local storage before
8857            // going to the content provider to open the file.  Later, in the code
8858            // that handles all permissions checks, we look for this uid and use
8859            // that rather than the Activity Manager's own uid.  The effect is that
8860            // we do the check against the caller's permissions even though it looks
8861            // to the content provider like the Activity Manager itself is making
8862            // the request.
8863            sCallerIdentity.set(new Identity(
8864                    Binder.getCallingPid(), Binder.getCallingUid()));
8865            try {
8866                pfd = cph.provider.openFile(null, uri, "r", null);
8867            } catch (FileNotFoundException e) {
8868                // do nothing; pfd will be returned null
8869            } finally {
8870                // Ensure that whatever happens, we clean up the identity state
8871                sCallerIdentity.remove();
8872            }
8873
8874            // We've got the fd now, so we're done with the provider.
8875            removeContentProviderExternalUnchecked(name, null, userId);
8876        } else {
8877            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8878        }
8879        return pfd;
8880    }
8881
8882    // Actually is sleeping or shutting down or whatever else in the future
8883    // is an inactive state.
8884    public boolean isSleepingOrShuttingDown() {
8885        return mSleeping || mShuttingDown;
8886    }
8887
8888    public boolean isSleeping() {
8889        return mSleeping;
8890    }
8891
8892    void goingToSleep() {
8893        synchronized(this) {
8894            mWentToSleep = true;
8895            updateEventDispatchingLocked();
8896            goToSleepIfNeededLocked();
8897        }
8898    }
8899
8900    void finishRunningVoiceLocked() {
8901        if (mRunningVoice) {
8902            mRunningVoice = false;
8903            goToSleepIfNeededLocked();
8904        }
8905    }
8906
8907    void goToSleepIfNeededLocked() {
8908        if (mWentToSleep && !mRunningVoice) {
8909            if (!mSleeping) {
8910                mSleeping = true;
8911                mStackSupervisor.goingToSleepLocked();
8912
8913                // Initialize the wake times of all processes.
8914                checkExcessivePowerUsageLocked(false);
8915                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8916                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8917                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8918            }
8919        }
8920    }
8921
8922    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8923        mTaskPersister.notify(task, flush);
8924    }
8925
8926    @Override
8927    public boolean shutdown(int timeout) {
8928        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8929                != PackageManager.PERMISSION_GRANTED) {
8930            throw new SecurityException("Requires permission "
8931                    + android.Manifest.permission.SHUTDOWN);
8932        }
8933
8934        boolean timedout = false;
8935
8936        synchronized(this) {
8937            mShuttingDown = true;
8938            updateEventDispatchingLocked();
8939            timedout = mStackSupervisor.shutdownLocked(timeout);
8940        }
8941
8942        mAppOpsService.shutdown();
8943        mUsageStatsService.shutdown();
8944        mBatteryStatsService.shutdown();
8945        synchronized (this) {
8946            mProcessStats.shutdownLocked();
8947        }
8948        notifyTaskPersisterLocked(null, true);
8949
8950        return timedout;
8951    }
8952
8953    public final void activitySlept(IBinder token) {
8954        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8955
8956        final long origId = Binder.clearCallingIdentity();
8957
8958        synchronized (this) {
8959            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8960            if (r != null) {
8961                mStackSupervisor.activitySleptLocked(r);
8962            }
8963        }
8964
8965        Binder.restoreCallingIdentity(origId);
8966    }
8967
8968    void logLockScreen(String msg) {
8969        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8970                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8971                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8972                mStackSupervisor.mDismissKeyguardOnNextActivity);
8973    }
8974
8975    private void comeOutOfSleepIfNeededLocked() {
8976        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8977            if (mSleeping) {
8978                mSleeping = false;
8979                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8980            }
8981        }
8982    }
8983
8984    void wakingUp() {
8985        synchronized(this) {
8986            mWentToSleep = false;
8987            updateEventDispatchingLocked();
8988            comeOutOfSleepIfNeededLocked();
8989        }
8990    }
8991
8992    void startRunningVoiceLocked() {
8993        if (!mRunningVoice) {
8994            mRunningVoice = true;
8995            comeOutOfSleepIfNeededLocked();
8996        }
8997    }
8998
8999    private void updateEventDispatchingLocked() {
9000        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9001    }
9002
9003    public void setLockScreenShown(boolean shown) {
9004        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9005                != PackageManager.PERMISSION_GRANTED) {
9006            throw new SecurityException("Requires permission "
9007                    + android.Manifest.permission.DEVICE_POWER);
9008        }
9009
9010        synchronized(this) {
9011            long ident = Binder.clearCallingIdentity();
9012            try {
9013                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9014                mLockScreenShown = shown;
9015                comeOutOfSleepIfNeededLocked();
9016            } finally {
9017                Binder.restoreCallingIdentity(ident);
9018            }
9019        }
9020    }
9021
9022    public void stopAppSwitches() {
9023        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9024                != PackageManager.PERMISSION_GRANTED) {
9025            throw new SecurityException("Requires permission "
9026                    + android.Manifest.permission.STOP_APP_SWITCHES);
9027        }
9028
9029        synchronized(this) {
9030            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9031                    + APP_SWITCH_DELAY_TIME;
9032            mDidAppSwitch = false;
9033            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9034            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9035            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9036        }
9037    }
9038
9039    public void resumeAppSwitches() {
9040        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9041                != PackageManager.PERMISSION_GRANTED) {
9042            throw new SecurityException("Requires permission "
9043                    + android.Manifest.permission.STOP_APP_SWITCHES);
9044        }
9045
9046        synchronized(this) {
9047            // Note that we don't execute any pending app switches... we will
9048            // let those wait until either the timeout, or the next start
9049            // activity request.
9050            mAppSwitchesAllowedTime = 0;
9051        }
9052    }
9053
9054    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9055            String name) {
9056        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9057            return true;
9058        }
9059
9060        final int perm = checkComponentPermission(
9061                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9062                callingUid, -1, true);
9063        if (perm == PackageManager.PERMISSION_GRANTED) {
9064            return true;
9065        }
9066
9067        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9068        return false;
9069    }
9070
9071    public void setDebugApp(String packageName, boolean waitForDebugger,
9072            boolean persistent) {
9073        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9074                "setDebugApp()");
9075
9076        long ident = Binder.clearCallingIdentity();
9077        try {
9078            // Note that this is not really thread safe if there are multiple
9079            // callers into it at the same time, but that's not a situation we
9080            // care about.
9081            if (persistent) {
9082                final ContentResolver resolver = mContext.getContentResolver();
9083                Settings.Global.putString(
9084                    resolver, Settings.Global.DEBUG_APP,
9085                    packageName);
9086                Settings.Global.putInt(
9087                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9088                    waitForDebugger ? 1 : 0);
9089            }
9090
9091            synchronized (this) {
9092                if (!persistent) {
9093                    mOrigDebugApp = mDebugApp;
9094                    mOrigWaitForDebugger = mWaitForDebugger;
9095                }
9096                mDebugApp = packageName;
9097                mWaitForDebugger = waitForDebugger;
9098                mDebugTransient = !persistent;
9099                if (packageName != null) {
9100                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9101                            false, UserHandle.USER_ALL, "set debug app");
9102                }
9103            }
9104        } finally {
9105            Binder.restoreCallingIdentity(ident);
9106        }
9107    }
9108
9109    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9110        synchronized (this) {
9111            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9112            if (!isDebuggable) {
9113                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9114                    throw new SecurityException("Process not debuggable: " + app.packageName);
9115                }
9116            }
9117
9118            mOpenGlTraceApp = processName;
9119        }
9120    }
9121
9122    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9123            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9124        synchronized (this) {
9125            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9126            if (!isDebuggable) {
9127                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9128                    throw new SecurityException("Process not debuggable: " + app.packageName);
9129                }
9130            }
9131            mProfileApp = processName;
9132            mProfileFile = profileFile;
9133            if (mProfileFd != null) {
9134                try {
9135                    mProfileFd.close();
9136                } catch (IOException e) {
9137                }
9138                mProfileFd = null;
9139            }
9140            mProfileFd = profileFd;
9141            mProfileType = 0;
9142            mAutoStopProfiler = autoStopProfiler;
9143        }
9144    }
9145
9146    @Override
9147    public void setAlwaysFinish(boolean enabled) {
9148        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9149                "setAlwaysFinish()");
9150
9151        Settings.Global.putInt(
9152                mContext.getContentResolver(),
9153                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9154
9155        synchronized (this) {
9156            mAlwaysFinishActivities = enabled;
9157        }
9158    }
9159
9160    @Override
9161    public void setActivityController(IActivityController controller) {
9162        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9163                "setActivityController()");
9164        synchronized (this) {
9165            mController = controller;
9166            Watchdog.getInstance().setActivityController(controller);
9167        }
9168    }
9169
9170    @Override
9171    public void setUserIsMonkey(boolean userIsMonkey) {
9172        synchronized (this) {
9173            synchronized (mPidsSelfLocked) {
9174                final int callingPid = Binder.getCallingPid();
9175                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9176                if (precessRecord == null) {
9177                    throw new SecurityException("Unknown process: " + callingPid);
9178                }
9179                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9180                    throw new SecurityException("Only an instrumentation process "
9181                            + "with a UiAutomation can call setUserIsMonkey");
9182                }
9183            }
9184            mUserIsMonkey = userIsMonkey;
9185        }
9186    }
9187
9188    @Override
9189    public boolean isUserAMonkey() {
9190        synchronized (this) {
9191            // If there is a controller also implies the user is a monkey.
9192            return (mUserIsMonkey || mController != null);
9193        }
9194    }
9195
9196    public void requestBugReport() {
9197        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9198        SystemProperties.set("ctl.start", "bugreport");
9199    }
9200
9201    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9202        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9203    }
9204
9205    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9206        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9207            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9208        }
9209        return KEY_DISPATCHING_TIMEOUT;
9210    }
9211
9212    @Override
9213    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9214        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9215                != PackageManager.PERMISSION_GRANTED) {
9216            throw new SecurityException("Requires permission "
9217                    + android.Manifest.permission.FILTER_EVENTS);
9218        }
9219        ProcessRecord proc;
9220        long timeout;
9221        synchronized (this) {
9222            synchronized (mPidsSelfLocked) {
9223                proc = mPidsSelfLocked.get(pid);
9224            }
9225            timeout = getInputDispatchingTimeoutLocked(proc);
9226        }
9227
9228        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9229            return -1;
9230        }
9231
9232        return timeout;
9233    }
9234
9235    /**
9236     * Handle input dispatching timeouts.
9237     * Returns whether input dispatching should be aborted or not.
9238     */
9239    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9240            final ActivityRecord activity, final ActivityRecord parent,
9241            final boolean aboveSystem, String reason) {
9242        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9243                != PackageManager.PERMISSION_GRANTED) {
9244            throw new SecurityException("Requires permission "
9245                    + android.Manifest.permission.FILTER_EVENTS);
9246        }
9247
9248        final String annotation;
9249        if (reason == null) {
9250            annotation = "Input dispatching timed out";
9251        } else {
9252            annotation = "Input dispatching timed out (" + reason + ")";
9253        }
9254
9255        if (proc != null) {
9256            synchronized (this) {
9257                if (proc.debugging) {
9258                    return false;
9259                }
9260
9261                if (mDidDexOpt) {
9262                    // Give more time since we were dexopting.
9263                    mDidDexOpt = false;
9264                    return false;
9265                }
9266
9267                if (proc.instrumentationClass != null) {
9268                    Bundle info = new Bundle();
9269                    info.putString("shortMsg", "keyDispatchingTimedOut");
9270                    info.putString("longMsg", annotation);
9271                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9272                    return true;
9273                }
9274            }
9275            mHandler.post(new Runnable() {
9276                @Override
9277                public void run() {
9278                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9279                }
9280            });
9281        }
9282
9283        return true;
9284    }
9285
9286    public Bundle getAssistContextExtras(int requestType) {
9287        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9288                "getAssistContextExtras()");
9289        PendingAssistExtras pae;
9290        Bundle extras = new Bundle();
9291        synchronized (this) {
9292            ActivityRecord activity = getFocusedStack().mResumedActivity;
9293            if (activity == null) {
9294                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9295                return null;
9296            }
9297            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9298            if (activity.app == null || activity.app.thread == null) {
9299                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9300                return extras;
9301            }
9302            if (activity.app.pid == Binder.getCallingPid()) {
9303                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9304                return extras;
9305            }
9306            pae = new PendingAssistExtras(activity);
9307            try {
9308                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9309                        requestType);
9310                mPendingAssistExtras.add(pae);
9311                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9312            } catch (RemoteException e) {
9313                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9314                return extras;
9315            }
9316        }
9317        synchronized (pae) {
9318            while (!pae.haveResult) {
9319                try {
9320                    pae.wait();
9321                } catch (InterruptedException e) {
9322                }
9323            }
9324            if (pae.result != null) {
9325                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9326            }
9327        }
9328        synchronized (this) {
9329            mPendingAssistExtras.remove(pae);
9330            mHandler.removeCallbacks(pae);
9331        }
9332        return extras;
9333    }
9334
9335    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9336        PendingAssistExtras pae = (PendingAssistExtras)token;
9337        synchronized (pae) {
9338            pae.result = extras;
9339            pae.haveResult = true;
9340            pae.notifyAll();
9341        }
9342    }
9343
9344    public void registerProcessObserver(IProcessObserver observer) {
9345        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9346                "registerProcessObserver()");
9347        synchronized (this) {
9348            mProcessObservers.register(observer);
9349        }
9350    }
9351
9352    @Override
9353    public void unregisterProcessObserver(IProcessObserver observer) {
9354        synchronized (this) {
9355            mProcessObservers.unregister(observer);
9356        }
9357    }
9358
9359    @Override
9360    public boolean convertFromTranslucent(IBinder token) {
9361        final long origId = Binder.clearCallingIdentity();
9362        try {
9363            synchronized (this) {
9364                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9365                if (r == null) {
9366                    return false;
9367                }
9368                if (r.changeWindowTranslucency(true)) {
9369                    mWindowManager.setAppFullscreen(token, true);
9370                    r.task.stack.releaseMediaResources();
9371                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9372                    return true;
9373                }
9374                return false;
9375            }
9376        } finally {
9377            Binder.restoreCallingIdentity(origId);
9378        }
9379    }
9380
9381    @Override
9382    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9383        final long origId = Binder.clearCallingIdentity();
9384        try {
9385            synchronized (this) {
9386                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9387                if (r == null) {
9388                    return false;
9389                }
9390                if (r.changeWindowTranslucency(false)) {
9391                    r.task.stack.convertToTranslucent(r, options);
9392                    mWindowManager.setAppFullscreen(token, false);
9393                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9394                    return true;
9395                } else {
9396                    r.task.stack.mReturningActivityOptions = options;
9397                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9398                    return false;
9399                }
9400            }
9401        } finally {
9402            Binder.restoreCallingIdentity(origId);
9403        }
9404    }
9405
9406    @Override
9407    public boolean setMediaPlaying(IBinder token, boolean playing) {
9408        final long origId = Binder.clearCallingIdentity();
9409        try {
9410            synchronized (this) {
9411                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9412                if (r != null) {
9413                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9414                }
9415            }
9416            return false;
9417        } finally {
9418            Binder.restoreCallingIdentity(origId);
9419        }
9420    }
9421
9422    @Override
9423    public boolean isBackgroundMediaPlaying(IBinder token) {
9424        final long origId = Binder.clearCallingIdentity();
9425        try {
9426            synchronized (this) {
9427                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9428                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9429                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9430                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9431                return playing;
9432            }
9433        } finally {
9434            Binder.restoreCallingIdentity(origId);
9435        }
9436    }
9437
9438    @Override
9439    public ActivityOptions getActivityOptions(IBinder token) {
9440        final long origId = Binder.clearCallingIdentity();
9441        try {
9442            synchronized (this) {
9443                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9444                if (r != null) {
9445                    final ActivityOptions activityOptions = r.pendingOptions;
9446                    r.pendingOptions = null;
9447                    return activityOptions;
9448                }
9449                return null;
9450            }
9451        } finally {
9452            Binder.restoreCallingIdentity(origId);
9453        }
9454    }
9455
9456    @Override
9457    public void setImmersive(IBinder token, boolean immersive) {
9458        synchronized(this) {
9459            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9460            if (r == null) {
9461                throw new IllegalArgumentException();
9462            }
9463            r.immersive = immersive;
9464
9465            // update associated state if we're frontmost
9466            if (r == mFocusedActivity) {
9467                if (DEBUG_IMMERSIVE) {
9468                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9469                }
9470                applyUpdateLockStateLocked(r);
9471            }
9472        }
9473    }
9474
9475    @Override
9476    public boolean isImmersive(IBinder token) {
9477        synchronized (this) {
9478            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9479            if (r == null) {
9480                throw new IllegalArgumentException();
9481            }
9482            return r.immersive;
9483        }
9484    }
9485
9486    public boolean isTopActivityImmersive() {
9487        enforceNotIsolatedCaller("startActivity");
9488        synchronized (this) {
9489            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9490            return (r != null) ? r.immersive : false;
9491        }
9492    }
9493
9494    @Override
9495    public boolean isTopOfTask(IBinder token) {
9496        synchronized (this) {
9497            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9498            if (r == null) {
9499                throw new IllegalArgumentException();
9500            }
9501            return r.task.getTopActivity() == r;
9502        }
9503    }
9504
9505    public final void enterSafeMode() {
9506        synchronized(this) {
9507            // It only makes sense to do this before the system is ready
9508            // and started launching other packages.
9509            if (!mSystemReady) {
9510                try {
9511                    AppGlobals.getPackageManager().enterSafeMode();
9512                } catch (RemoteException e) {
9513                }
9514            }
9515
9516            mSafeMode = true;
9517        }
9518    }
9519
9520    public final void showSafeModeOverlay() {
9521        View v = LayoutInflater.from(mContext).inflate(
9522                com.android.internal.R.layout.safe_mode, null);
9523        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9524        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9525        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9526        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9527        lp.gravity = Gravity.BOTTOM | Gravity.START;
9528        lp.format = v.getBackground().getOpacity();
9529        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9530                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9531        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9532        ((WindowManager)mContext.getSystemService(
9533                Context.WINDOW_SERVICE)).addView(v, lp);
9534    }
9535
9536    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9537        if (!(sender instanceof PendingIntentRecord)) {
9538            return;
9539        }
9540        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9541        synchronized (stats) {
9542            if (mBatteryStatsService.isOnBattery()) {
9543                mBatteryStatsService.enforceCallingPermission();
9544                PendingIntentRecord rec = (PendingIntentRecord)sender;
9545                int MY_UID = Binder.getCallingUid();
9546                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9547                BatteryStatsImpl.Uid.Pkg pkg =
9548                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9549                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9550                pkg.incWakeupsLocked();
9551            }
9552        }
9553    }
9554
9555    public boolean killPids(int[] pids, String pReason, boolean secure) {
9556        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9557            throw new SecurityException("killPids only available to the system");
9558        }
9559        String reason = (pReason == null) ? "Unknown" : pReason;
9560        // XXX Note: don't acquire main activity lock here, because the window
9561        // manager calls in with its locks held.
9562
9563        boolean killed = false;
9564        synchronized (mPidsSelfLocked) {
9565            int[] types = new int[pids.length];
9566            int worstType = 0;
9567            for (int i=0; i<pids.length; i++) {
9568                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9569                if (proc != null) {
9570                    int type = proc.setAdj;
9571                    types[i] = type;
9572                    if (type > worstType) {
9573                        worstType = type;
9574                    }
9575                }
9576            }
9577
9578            // If the worst oom_adj is somewhere in the cached proc LRU range,
9579            // then constrain it so we will kill all cached procs.
9580            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9581                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9582                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9583            }
9584
9585            // If this is not a secure call, don't let it kill processes that
9586            // are important.
9587            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9588                worstType = ProcessList.SERVICE_ADJ;
9589            }
9590
9591            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9592            for (int i=0; i<pids.length; i++) {
9593                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9594                if (proc == null) {
9595                    continue;
9596                }
9597                int adj = proc.setAdj;
9598                if (adj >= worstType && !proc.killedByAm) {
9599                    killUnneededProcessLocked(proc, reason);
9600                    killed = true;
9601                }
9602            }
9603        }
9604        return killed;
9605    }
9606
9607    @Override
9608    public void killUid(int uid, String reason) {
9609        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9610            throw new SecurityException("killUid only available to the system");
9611        }
9612        synchronized (this) {
9613            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9614                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9615                    reason != null ? reason : "kill uid");
9616        }
9617    }
9618
9619    @Override
9620    public boolean killProcessesBelowForeground(String reason) {
9621        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9622            throw new SecurityException("killProcessesBelowForeground() only available to system");
9623        }
9624
9625        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9626    }
9627
9628    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9629        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9630            throw new SecurityException("killProcessesBelowAdj() only available to system");
9631        }
9632
9633        boolean killed = false;
9634        synchronized (mPidsSelfLocked) {
9635            final int size = mPidsSelfLocked.size();
9636            for (int i = 0; i < size; i++) {
9637                final int pid = mPidsSelfLocked.keyAt(i);
9638                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9639                if (proc == null) continue;
9640
9641                final int adj = proc.setAdj;
9642                if (adj > belowAdj && !proc.killedByAm) {
9643                    killUnneededProcessLocked(proc, reason);
9644                    killed = true;
9645                }
9646            }
9647        }
9648        return killed;
9649    }
9650
9651    @Override
9652    public void hang(final IBinder who, boolean allowRestart) {
9653        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9654                != PackageManager.PERMISSION_GRANTED) {
9655            throw new SecurityException("Requires permission "
9656                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9657        }
9658
9659        final IBinder.DeathRecipient death = new DeathRecipient() {
9660            @Override
9661            public void binderDied() {
9662                synchronized (this) {
9663                    notifyAll();
9664                }
9665            }
9666        };
9667
9668        try {
9669            who.linkToDeath(death, 0);
9670        } catch (RemoteException e) {
9671            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9672            return;
9673        }
9674
9675        synchronized (this) {
9676            Watchdog.getInstance().setAllowRestart(allowRestart);
9677            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9678            synchronized (death) {
9679                while (who.isBinderAlive()) {
9680                    try {
9681                        death.wait();
9682                    } catch (InterruptedException e) {
9683                    }
9684                }
9685            }
9686            Watchdog.getInstance().setAllowRestart(true);
9687        }
9688    }
9689
9690    @Override
9691    public void restart() {
9692        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9693                != PackageManager.PERMISSION_GRANTED) {
9694            throw new SecurityException("Requires permission "
9695                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9696        }
9697
9698        Log.i(TAG, "Sending shutdown broadcast...");
9699
9700        BroadcastReceiver br = new BroadcastReceiver() {
9701            @Override public void onReceive(Context context, Intent intent) {
9702                // Now the broadcast is done, finish up the low-level shutdown.
9703                Log.i(TAG, "Shutting down activity manager...");
9704                shutdown(10000);
9705                Log.i(TAG, "Shutdown complete, restarting!");
9706                Process.killProcess(Process.myPid());
9707                System.exit(10);
9708            }
9709        };
9710
9711        // First send the high-level shut down broadcast.
9712        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9713        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9714        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9715        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9716        mContext.sendOrderedBroadcastAsUser(intent,
9717                UserHandle.ALL, null, br, mHandler, 0, null, null);
9718        */
9719        br.onReceive(mContext, intent);
9720    }
9721
9722    private long getLowRamTimeSinceIdle(long now) {
9723        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9724    }
9725
9726    @Override
9727    public void performIdleMaintenance() {
9728        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9729                != PackageManager.PERMISSION_GRANTED) {
9730            throw new SecurityException("Requires permission "
9731                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9732        }
9733
9734        synchronized (this) {
9735            final long now = SystemClock.uptimeMillis();
9736            final long timeSinceLastIdle = now - mLastIdleTime;
9737            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9738            mLastIdleTime = now;
9739            mLowRamTimeSinceLastIdle = 0;
9740            if (mLowRamStartTime != 0) {
9741                mLowRamStartTime = now;
9742            }
9743
9744            StringBuilder sb = new StringBuilder(128);
9745            sb.append("Idle maintenance over ");
9746            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9747            sb.append(" low RAM for ");
9748            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9749            Slog.i(TAG, sb.toString());
9750
9751            // If at least 1/3 of our time since the last idle period has been spent
9752            // with RAM low, then we want to kill processes.
9753            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9754
9755            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9756                ProcessRecord proc = mLruProcesses.get(i);
9757                if (proc.notCachedSinceIdle) {
9758                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9759                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9760                        if (doKilling && proc.initialIdlePss != 0
9761                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9762                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9763                                    + " from " + proc.initialIdlePss + ")");
9764                        }
9765                    }
9766                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9767                    proc.notCachedSinceIdle = true;
9768                    proc.initialIdlePss = 0;
9769                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9770                            isSleeping(), now);
9771                }
9772            }
9773
9774            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9775            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9776        }
9777    }
9778
9779    private void retrieveSettings() {
9780        final ContentResolver resolver = mContext.getContentResolver();
9781        String debugApp = Settings.Global.getString(
9782            resolver, Settings.Global.DEBUG_APP);
9783        boolean waitForDebugger = Settings.Global.getInt(
9784            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9785        boolean alwaysFinishActivities = Settings.Global.getInt(
9786            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9787        boolean forceRtl = Settings.Global.getInt(
9788                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9789        // Transfer any global setting for forcing RTL layout, into a System Property
9790        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9791
9792        Configuration configuration = new Configuration();
9793        Settings.System.getConfiguration(resolver, configuration);
9794        if (forceRtl) {
9795            // This will take care of setting the correct layout direction flags
9796            configuration.setLayoutDirection(configuration.locale);
9797        }
9798
9799        synchronized (this) {
9800            mDebugApp = mOrigDebugApp = debugApp;
9801            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9802            mAlwaysFinishActivities = alwaysFinishActivities;
9803            // This happens before any activities are started, so we can
9804            // change mConfiguration in-place.
9805            updateConfigurationLocked(configuration, null, false, true);
9806            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9807        }
9808    }
9809
9810    public boolean testIsSystemReady() {
9811        // no need to synchronize(this) just to read & return the value
9812        return mSystemReady;
9813    }
9814
9815    private static File getCalledPreBootReceiversFile() {
9816        File dataDir = Environment.getDataDirectory();
9817        File systemDir = new File(dataDir, "system");
9818        File fname = new File(systemDir, "called_pre_boots.dat");
9819        return fname;
9820    }
9821
9822    static final int LAST_DONE_VERSION = 10000;
9823
9824    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9825        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9826        File file = getCalledPreBootReceiversFile();
9827        FileInputStream fis = null;
9828        try {
9829            fis = new FileInputStream(file);
9830            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9831            int fvers = dis.readInt();
9832            if (fvers == LAST_DONE_VERSION) {
9833                String vers = dis.readUTF();
9834                String codename = dis.readUTF();
9835                String build = dis.readUTF();
9836                if (android.os.Build.VERSION.RELEASE.equals(vers)
9837                        && android.os.Build.VERSION.CODENAME.equals(codename)
9838                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9839                    int num = dis.readInt();
9840                    while (num > 0) {
9841                        num--;
9842                        String pkg = dis.readUTF();
9843                        String cls = dis.readUTF();
9844                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9845                    }
9846                }
9847            }
9848        } catch (FileNotFoundException e) {
9849        } catch (IOException e) {
9850            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9851        } finally {
9852            if (fis != null) {
9853                try {
9854                    fis.close();
9855                } catch (IOException e) {
9856                }
9857            }
9858        }
9859        return lastDoneReceivers;
9860    }
9861
9862    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9863        File file = getCalledPreBootReceiversFile();
9864        FileOutputStream fos = null;
9865        DataOutputStream dos = null;
9866        try {
9867            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9868            fos = new FileOutputStream(file);
9869            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9870            dos.writeInt(LAST_DONE_VERSION);
9871            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9872            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9873            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9874            dos.writeInt(list.size());
9875            for (int i=0; i<list.size(); i++) {
9876                dos.writeUTF(list.get(i).getPackageName());
9877                dos.writeUTF(list.get(i).getClassName());
9878            }
9879        } catch (IOException e) {
9880            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9881            file.delete();
9882        } finally {
9883            FileUtils.sync(fos);
9884            if (dos != null) {
9885                try {
9886                    dos.close();
9887                } catch (IOException e) {
9888                    // TODO Auto-generated catch block
9889                    e.printStackTrace();
9890                }
9891            }
9892        }
9893    }
9894
9895    public void systemReady(final Runnable goingCallback) {
9896        synchronized(this) {
9897            if (mSystemReady) {
9898                if (goingCallback != null) goingCallback.run();
9899                return;
9900            }
9901
9902            if (mRecentTasks == null) {
9903                mRecentTasks = mTaskPersister.restoreTasksLocked();
9904                if (!mRecentTasks.isEmpty()) {
9905                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9906                }
9907                mTaskPersister.startPersisting();
9908            }
9909
9910            // Check to see if there are any update receivers to run.
9911            if (!mDidUpdate) {
9912                if (mWaitingUpdate) {
9913                    return;
9914                }
9915                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9916                List<ResolveInfo> ris = null;
9917                try {
9918                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9919                            intent, null, 0, 0);
9920                } catch (RemoteException e) {
9921                }
9922                if (ris != null) {
9923                    for (int i=ris.size()-1; i>=0; i--) {
9924                        if ((ris.get(i).activityInfo.applicationInfo.flags
9925                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9926                            ris.remove(i);
9927                        }
9928                    }
9929                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9930
9931                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9932
9933                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9934                    for (int i=0; i<ris.size(); i++) {
9935                        ActivityInfo ai = ris.get(i).activityInfo;
9936                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9937                        if (lastDoneReceivers.contains(comp)) {
9938                            // We already did the pre boot receiver for this app with the current
9939                            // platform version, so don't do it again...
9940                            ris.remove(i);
9941                            i--;
9942                            // ...however, do keep it as one that has been done, so we don't
9943                            // forget about it when rewriting the file of last done receivers.
9944                            doneReceivers.add(comp);
9945                        }
9946                    }
9947
9948                    final int[] users = getUsersLocked();
9949                    for (int i=0; i<ris.size(); i++) {
9950                        ActivityInfo ai = ris.get(i).activityInfo;
9951                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9952                        doneReceivers.add(comp);
9953                        intent.setComponent(comp);
9954                        for (int j=0; j<users.length; j++) {
9955                            IIntentReceiver finisher = null;
9956                            if (i == ris.size()-1 && j == users.length-1) {
9957                                finisher = new IIntentReceiver.Stub() {
9958                                    public void performReceive(Intent intent, int resultCode,
9959                                            String data, Bundle extras, boolean ordered,
9960                                            boolean sticky, int sendingUser) {
9961                                        // The raw IIntentReceiver interface is called
9962                                        // with the AM lock held, so redispatch to
9963                                        // execute our code without the lock.
9964                                        mHandler.post(new Runnable() {
9965                                            public void run() {
9966                                                synchronized (ActivityManagerService.this) {
9967                                                    mDidUpdate = true;
9968                                                }
9969                                                writeLastDonePreBootReceivers(doneReceivers);
9970                                                showBootMessage(mContext.getText(
9971                                                        R.string.android_upgrading_complete),
9972                                                        false);
9973                                                systemReady(goingCallback);
9974                                            }
9975                                        });
9976                                    }
9977                                };
9978                            }
9979                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9980                                    + " for user " + users[j]);
9981                            broadcastIntentLocked(null, null, intent, null, finisher,
9982                                    0, null, null, null, AppOpsManager.OP_NONE,
9983                                    true, false, MY_PID, Process.SYSTEM_UID,
9984                                    users[j]);
9985                            if (finisher != null) {
9986                                mWaitingUpdate = true;
9987                            }
9988                        }
9989                    }
9990                }
9991                if (mWaitingUpdate) {
9992                    return;
9993                }
9994                mDidUpdate = true;
9995            }
9996
9997            mAppOpsService.systemReady();
9998            mUsageStatsService.systemReady();
9999            mSystemReady = true;
10000        }
10001
10002        ArrayList<ProcessRecord> procsToKill = null;
10003        synchronized(mPidsSelfLocked) {
10004            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10005                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10006                if (!isAllowedWhileBooting(proc.info)){
10007                    if (procsToKill == null) {
10008                        procsToKill = new ArrayList<ProcessRecord>();
10009                    }
10010                    procsToKill.add(proc);
10011                }
10012            }
10013        }
10014
10015        synchronized(this) {
10016            if (procsToKill != null) {
10017                for (int i=procsToKill.size()-1; i>=0; i--) {
10018                    ProcessRecord proc = procsToKill.get(i);
10019                    Slog.i(TAG, "Removing system update proc: " + proc);
10020                    removeProcessLocked(proc, true, false, "system update done");
10021                }
10022            }
10023
10024            // Now that we have cleaned up any update processes, we
10025            // are ready to start launching real processes and know that
10026            // we won't trample on them any more.
10027            mProcessesReady = true;
10028        }
10029
10030        Slog.i(TAG, "System now ready");
10031        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10032            SystemClock.uptimeMillis());
10033
10034        synchronized(this) {
10035            // Make sure we have no pre-ready processes sitting around.
10036
10037            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10038                ResolveInfo ri = mContext.getPackageManager()
10039                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10040                                STOCK_PM_FLAGS);
10041                CharSequence errorMsg = null;
10042                if (ri != null) {
10043                    ActivityInfo ai = ri.activityInfo;
10044                    ApplicationInfo app = ai.applicationInfo;
10045                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10046                        mTopAction = Intent.ACTION_FACTORY_TEST;
10047                        mTopData = null;
10048                        mTopComponent = new ComponentName(app.packageName,
10049                                ai.name);
10050                    } else {
10051                        errorMsg = mContext.getResources().getText(
10052                                com.android.internal.R.string.factorytest_not_system);
10053                    }
10054                } else {
10055                    errorMsg = mContext.getResources().getText(
10056                            com.android.internal.R.string.factorytest_no_action);
10057                }
10058                if (errorMsg != null) {
10059                    mTopAction = null;
10060                    mTopData = null;
10061                    mTopComponent = null;
10062                    Message msg = Message.obtain();
10063                    msg.what = SHOW_FACTORY_ERROR_MSG;
10064                    msg.getData().putCharSequence("msg", errorMsg);
10065                    mHandler.sendMessage(msg);
10066                }
10067            }
10068        }
10069
10070        retrieveSettings();
10071
10072        synchronized (this) {
10073            readGrantedUriPermissionsLocked();
10074        }
10075
10076        if (goingCallback != null) goingCallback.run();
10077
10078        mSystemServiceManager.startUser(mCurrentUserId);
10079
10080        synchronized (this) {
10081            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10082                try {
10083                    List apps = AppGlobals.getPackageManager().
10084                        getPersistentApplications(STOCK_PM_FLAGS);
10085                    if (apps != null) {
10086                        int N = apps.size();
10087                        int i;
10088                        for (i=0; i<N; i++) {
10089                            ApplicationInfo info
10090                                = (ApplicationInfo)apps.get(i);
10091                            if (info != null &&
10092                                    !info.packageName.equals("android")) {
10093                                addAppLocked(info, false, null /* ABI override */);
10094                            }
10095                        }
10096                    }
10097                } catch (RemoteException ex) {
10098                    // pm is in same process, this will never happen.
10099                }
10100            }
10101
10102            // Start up initial activity.
10103            mBooting = true;
10104
10105            try {
10106                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10107                    Message msg = Message.obtain();
10108                    msg.what = SHOW_UID_ERROR_MSG;
10109                    mHandler.sendMessage(msg);
10110                }
10111            } catch (RemoteException e) {
10112            }
10113
10114            long ident = Binder.clearCallingIdentity();
10115            try {
10116                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10117                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10118                        | Intent.FLAG_RECEIVER_FOREGROUND);
10119                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10120                broadcastIntentLocked(null, null, intent,
10121                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10122                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10123                intent = new Intent(Intent.ACTION_USER_STARTING);
10124                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10125                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10126                broadcastIntentLocked(null, null, intent,
10127                        null, new IIntentReceiver.Stub() {
10128                            @Override
10129                            public void performReceive(Intent intent, int resultCode, String data,
10130                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10131                                    throws RemoteException {
10132                            }
10133                        }, 0, null, null,
10134                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10135                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10136            } catch (Throwable t) {
10137                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10138            } finally {
10139                Binder.restoreCallingIdentity(ident);
10140            }
10141            mStackSupervisor.resumeTopActivitiesLocked();
10142            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10143        }
10144    }
10145
10146    private boolean makeAppCrashingLocked(ProcessRecord app,
10147            String shortMsg, String longMsg, String stackTrace) {
10148        app.crashing = true;
10149        app.crashingReport = generateProcessError(app,
10150                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10151        startAppProblemLocked(app);
10152        app.stopFreezingAllLocked();
10153        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10154    }
10155
10156    private void makeAppNotRespondingLocked(ProcessRecord app,
10157            String activity, String shortMsg, String longMsg) {
10158        app.notResponding = true;
10159        app.notRespondingReport = generateProcessError(app,
10160                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10161                activity, shortMsg, longMsg, null);
10162        startAppProblemLocked(app);
10163        app.stopFreezingAllLocked();
10164    }
10165
10166    /**
10167     * Generate a process error record, suitable for attachment to a ProcessRecord.
10168     *
10169     * @param app The ProcessRecord in which the error occurred.
10170     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10171     *                      ActivityManager.AppErrorStateInfo
10172     * @param activity The activity associated with the crash, if known.
10173     * @param shortMsg Short message describing the crash.
10174     * @param longMsg Long message describing the crash.
10175     * @param stackTrace Full crash stack trace, may be null.
10176     *
10177     * @return Returns a fully-formed AppErrorStateInfo record.
10178     */
10179    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10180            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10181        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10182
10183        report.condition = condition;
10184        report.processName = app.processName;
10185        report.pid = app.pid;
10186        report.uid = app.info.uid;
10187        report.tag = activity;
10188        report.shortMsg = shortMsg;
10189        report.longMsg = longMsg;
10190        report.stackTrace = stackTrace;
10191
10192        return report;
10193    }
10194
10195    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10196        synchronized (this) {
10197            app.crashing = false;
10198            app.crashingReport = null;
10199            app.notResponding = false;
10200            app.notRespondingReport = null;
10201            if (app.anrDialog == fromDialog) {
10202                app.anrDialog = null;
10203            }
10204            if (app.waitDialog == fromDialog) {
10205                app.waitDialog = null;
10206            }
10207            if (app.pid > 0 && app.pid != MY_PID) {
10208                handleAppCrashLocked(app, null, null, null);
10209                killUnneededProcessLocked(app, "user request after error");
10210            }
10211        }
10212    }
10213
10214    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10215            String stackTrace) {
10216        long now = SystemClock.uptimeMillis();
10217
10218        Long crashTime;
10219        if (!app.isolated) {
10220            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10221        } else {
10222            crashTime = null;
10223        }
10224        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10225            // This process loses!
10226            Slog.w(TAG, "Process " + app.info.processName
10227                    + " has crashed too many times: killing!");
10228            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10229                    app.userId, app.info.processName, app.uid);
10230            mStackSupervisor.handleAppCrashLocked(app);
10231            if (!app.persistent) {
10232                // We don't want to start this process again until the user
10233                // explicitly does so...  but for persistent process, we really
10234                // need to keep it running.  If a persistent process is actually
10235                // repeatedly crashing, then badness for everyone.
10236                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10237                        app.info.processName);
10238                if (!app.isolated) {
10239                    // XXX We don't have a way to mark isolated processes
10240                    // as bad, since they don't have a peristent identity.
10241                    mBadProcesses.put(app.info.processName, app.uid,
10242                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10243                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10244                }
10245                app.bad = true;
10246                app.removed = true;
10247                // Don't let services in this process be restarted and potentially
10248                // annoy the user repeatedly.  Unless it is persistent, since those
10249                // processes run critical code.
10250                removeProcessLocked(app, false, false, "crash");
10251                mStackSupervisor.resumeTopActivitiesLocked();
10252                return false;
10253            }
10254            mStackSupervisor.resumeTopActivitiesLocked();
10255        } else {
10256            mStackSupervisor.finishTopRunningActivityLocked(app);
10257        }
10258
10259        // Bump up the crash count of any services currently running in the proc.
10260        for (int i=app.services.size()-1; i>=0; i--) {
10261            // Any services running in the application need to be placed
10262            // back in the pending list.
10263            ServiceRecord sr = app.services.valueAt(i);
10264            sr.crashCount++;
10265        }
10266
10267        // If the crashing process is what we consider to be the "home process" and it has been
10268        // replaced by a third-party app, clear the package preferred activities from packages
10269        // with a home activity running in the process to prevent a repeatedly crashing app
10270        // from blocking the user to manually clear the list.
10271        final ArrayList<ActivityRecord> activities = app.activities;
10272        if (app == mHomeProcess && activities.size() > 0
10273                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10274            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10275                final ActivityRecord r = activities.get(activityNdx);
10276                if (r.isHomeActivity()) {
10277                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10278                    try {
10279                        ActivityThread.getPackageManager()
10280                                .clearPackagePreferredActivities(r.packageName);
10281                    } catch (RemoteException c) {
10282                        // pm is in same process, this will never happen.
10283                    }
10284                }
10285            }
10286        }
10287
10288        if (!app.isolated) {
10289            // XXX Can't keep track of crash times for isolated processes,
10290            // because they don't have a perisistent identity.
10291            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10292        }
10293
10294        return true;
10295    }
10296
10297    void startAppProblemLocked(ProcessRecord app) {
10298        if (app.userId == mCurrentUserId) {
10299            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10300                    mContext, app.info.packageName, app.info.flags);
10301        } else {
10302            // If this app is not running under the current user, then we
10303            // can't give it a report button because that would require
10304            // launching the report UI under a different user.
10305            app.errorReportReceiver = null;
10306        }
10307        skipCurrentReceiverLocked(app);
10308    }
10309
10310    void skipCurrentReceiverLocked(ProcessRecord app) {
10311        for (BroadcastQueue queue : mBroadcastQueues) {
10312            queue.skipCurrentReceiverLocked(app);
10313        }
10314    }
10315
10316    /**
10317     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10318     * The application process will exit immediately after this call returns.
10319     * @param app object of the crashing app, null for the system server
10320     * @param crashInfo describing the exception
10321     */
10322    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10323        ProcessRecord r = findAppProcess(app, "Crash");
10324        final String processName = app == null ? "system_server"
10325                : (r == null ? "unknown" : r.processName);
10326
10327        handleApplicationCrashInner("crash", r, processName, crashInfo);
10328    }
10329
10330    /* Native crash reporting uses this inner version because it needs to be somewhat
10331     * decoupled from the AM-managed cleanup lifecycle
10332     */
10333    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10334            ApplicationErrorReport.CrashInfo crashInfo) {
10335        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10336                UserHandle.getUserId(Binder.getCallingUid()), processName,
10337                r == null ? -1 : r.info.flags,
10338                crashInfo.exceptionClassName,
10339                crashInfo.exceptionMessage,
10340                crashInfo.throwFileName,
10341                crashInfo.throwLineNumber);
10342
10343        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10344
10345        crashApplication(r, crashInfo);
10346    }
10347
10348    public void handleApplicationStrictModeViolation(
10349            IBinder app,
10350            int violationMask,
10351            StrictMode.ViolationInfo info) {
10352        ProcessRecord r = findAppProcess(app, "StrictMode");
10353        if (r == null) {
10354            return;
10355        }
10356
10357        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10358            Integer stackFingerprint = info.hashCode();
10359            boolean logIt = true;
10360            synchronized (mAlreadyLoggedViolatedStacks) {
10361                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10362                    logIt = false;
10363                    // TODO: sub-sample into EventLog for these, with
10364                    // the info.durationMillis?  Then we'd get
10365                    // the relative pain numbers, without logging all
10366                    // the stack traces repeatedly.  We'd want to do
10367                    // likewise in the client code, which also does
10368                    // dup suppression, before the Binder call.
10369                } else {
10370                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10371                        mAlreadyLoggedViolatedStacks.clear();
10372                    }
10373                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10374                }
10375            }
10376            if (logIt) {
10377                logStrictModeViolationToDropBox(r, info);
10378            }
10379        }
10380
10381        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10382            AppErrorResult result = new AppErrorResult();
10383            synchronized (this) {
10384                final long origId = Binder.clearCallingIdentity();
10385
10386                Message msg = Message.obtain();
10387                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10388                HashMap<String, Object> data = new HashMap<String, Object>();
10389                data.put("result", result);
10390                data.put("app", r);
10391                data.put("violationMask", violationMask);
10392                data.put("info", info);
10393                msg.obj = data;
10394                mHandler.sendMessage(msg);
10395
10396                Binder.restoreCallingIdentity(origId);
10397            }
10398            int res = result.get();
10399            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10400        }
10401    }
10402
10403    // Depending on the policy in effect, there could be a bunch of
10404    // these in quick succession so we try to batch these together to
10405    // minimize disk writes, number of dropbox entries, and maximize
10406    // compression, by having more fewer, larger records.
10407    private void logStrictModeViolationToDropBox(
10408            ProcessRecord process,
10409            StrictMode.ViolationInfo info) {
10410        if (info == null) {
10411            return;
10412        }
10413        final boolean isSystemApp = process == null ||
10414                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10415                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10416        final String processName = process == null ? "unknown" : process.processName;
10417        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10418        final DropBoxManager dbox = (DropBoxManager)
10419                mContext.getSystemService(Context.DROPBOX_SERVICE);
10420
10421        // Exit early if the dropbox isn't configured to accept this report type.
10422        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10423
10424        boolean bufferWasEmpty;
10425        boolean needsFlush;
10426        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10427        synchronized (sb) {
10428            bufferWasEmpty = sb.length() == 0;
10429            appendDropBoxProcessHeaders(process, processName, sb);
10430            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10431            sb.append("System-App: ").append(isSystemApp).append("\n");
10432            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10433            if (info.violationNumThisLoop != 0) {
10434                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10435            }
10436            if (info.numAnimationsRunning != 0) {
10437                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10438            }
10439            if (info.broadcastIntentAction != null) {
10440                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10441            }
10442            if (info.durationMillis != -1) {
10443                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10444            }
10445            if (info.numInstances != -1) {
10446                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10447            }
10448            if (info.tags != null) {
10449                for (String tag : info.tags) {
10450                    sb.append("Span-Tag: ").append(tag).append("\n");
10451                }
10452            }
10453            sb.append("\n");
10454            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10455                sb.append(info.crashInfo.stackTrace);
10456            }
10457            sb.append("\n");
10458
10459            // Only buffer up to ~64k.  Various logging bits truncate
10460            // things at 128k.
10461            needsFlush = (sb.length() > 64 * 1024);
10462        }
10463
10464        // Flush immediately if the buffer's grown too large, or this
10465        // is a non-system app.  Non-system apps are isolated with a
10466        // different tag & policy and not batched.
10467        //
10468        // Batching is useful during internal testing with
10469        // StrictMode settings turned up high.  Without batching,
10470        // thousands of separate files could be created on boot.
10471        if (!isSystemApp || needsFlush) {
10472            new Thread("Error dump: " + dropboxTag) {
10473                @Override
10474                public void run() {
10475                    String report;
10476                    synchronized (sb) {
10477                        report = sb.toString();
10478                        sb.delete(0, sb.length());
10479                        sb.trimToSize();
10480                    }
10481                    if (report.length() != 0) {
10482                        dbox.addText(dropboxTag, report);
10483                    }
10484                }
10485            }.start();
10486            return;
10487        }
10488
10489        // System app batching:
10490        if (!bufferWasEmpty) {
10491            // An existing dropbox-writing thread is outstanding, so
10492            // we don't need to start it up.  The existing thread will
10493            // catch the buffer appends we just did.
10494            return;
10495        }
10496
10497        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10498        // (After this point, we shouldn't access AMS internal data structures.)
10499        new Thread("Error dump: " + dropboxTag) {
10500            @Override
10501            public void run() {
10502                // 5 second sleep to let stacks arrive and be batched together
10503                try {
10504                    Thread.sleep(5000);  // 5 seconds
10505                } catch (InterruptedException e) {}
10506
10507                String errorReport;
10508                synchronized (mStrictModeBuffer) {
10509                    errorReport = mStrictModeBuffer.toString();
10510                    if (errorReport.length() == 0) {
10511                        return;
10512                    }
10513                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10514                    mStrictModeBuffer.trimToSize();
10515                }
10516                dbox.addText(dropboxTag, errorReport);
10517            }
10518        }.start();
10519    }
10520
10521    /**
10522     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10523     * @param app object of the crashing app, null for the system server
10524     * @param tag reported by the caller
10525     * @param crashInfo describing the context of the error
10526     * @return true if the process should exit immediately (WTF is fatal)
10527     */
10528    public boolean handleApplicationWtf(IBinder app, String tag,
10529            ApplicationErrorReport.CrashInfo crashInfo) {
10530        ProcessRecord r = findAppProcess(app, "WTF");
10531        final String processName = app == null ? "system_server"
10532                : (r == null ? "unknown" : r.processName);
10533
10534        EventLog.writeEvent(EventLogTags.AM_WTF,
10535                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10536                processName,
10537                r == null ? -1 : r.info.flags,
10538                tag, crashInfo.exceptionMessage);
10539
10540        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10541
10542        if (r != null && r.pid != Process.myPid() &&
10543                Settings.Global.getInt(mContext.getContentResolver(),
10544                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10545            crashApplication(r, crashInfo);
10546            return true;
10547        } else {
10548            return false;
10549        }
10550    }
10551
10552    /**
10553     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10554     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10555     */
10556    private ProcessRecord findAppProcess(IBinder app, String reason) {
10557        if (app == null) {
10558            return null;
10559        }
10560
10561        synchronized (this) {
10562            final int NP = mProcessNames.getMap().size();
10563            for (int ip=0; ip<NP; ip++) {
10564                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10565                final int NA = apps.size();
10566                for (int ia=0; ia<NA; ia++) {
10567                    ProcessRecord p = apps.valueAt(ia);
10568                    if (p.thread != null && p.thread.asBinder() == app) {
10569                        return p;
10570                    }
10571                }
10572            }
10573
10574            Slog.w(TAG, "Can't find mystery application for " + reason
10575                    + " from pid=" + Binder.getCallingPid()
10576                    + " uid=" + Binder.getCallingUid() + ": " + app);
10577            return null;
10578        }
10579    }
10580
10581    /**
10582     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10583     * to append various headers to the dropbox log text.
10584     */
10585    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10586            StringBuilder sb) {
10587        // Watchdog thread ends up invoking this function (with
10588        // a null ProcessRecord) to add the stack file to dropbox.
10589        // Do not acquire a lock on this (am) in such cases, as it
10590        // could cause a potential deadlock, if and when watchdog
10591        // is invoked due to unavailability of lock on am and it
10592        // would prevent watchdog from killing system_server.
10593        if (process == null) {
10594            sb.append("Process: ").append(processName).append("\n");
10595            return;
10596        }
10597        // Note: ProcessRecord 'process' is guarded by the service
10598        // instance.  (notably process.pkgList, which could otherwise change
10599        // concurrently during execution of this method)
10600        synchronized (this) {
10601            sb.append("Process: ").append(processName).append("\n");
10602            int flags = process.info.flags;
10603            IPackageManager pm = AppGlobals.getPackageManager();
10604            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10605            for (int ip=0; ip<process.pkgList.size(); ip++) {
10606                String pkg = process.pkgList.keyAt(ip);
10607                sb.append("Package: ").append(pkg);
10608                try {
10609                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10610                    if (pi != null) {
10611                        sb.append(" v").append(pi.versionCode);
10612                        if (pi.versionName != null) {
10613                            sb.append(" (").append(pi.versionName).append(")");
10614                        }
10615                    }
10616                } catch (RemoteException e) {
10617                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10618                }
10619                sb.append("\n");
10620            }
10621        }
10622    }
10623
10624    private static String processClass(ProcessRecord process) {
10625        if (process == null || process.pid == MY_PID) {
10626            return "system_server";
10627        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10628            return "system_app";
10629        } else {
10630            return "data_app";
10631        }
10632    }
10633
10634    /**
10635     * Write a description of an error (crash, WTF, ANR) to the drop box.
10636     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10637     * @param process which caused the error, null means the system server
10638     * @param activity which triggered the error, null if unknown
10639     * @param parent activity related to the error, null if unknown
10640     * @param subject line related to the error, null if absent
10641     * @param report in long form describing the error, null if absent
10642     * @param logFile to include in the report, null if none
10643     * @param crashInfo giving an application stack trace, null if absent
10644     */
10645    public void addErrorToDropBox(String eventType,
10646            ProcessRecord process, String processName, ActivityRecord activity,
10647            ActivityRecord parent, String subject,
10648            final String report, final File logFile,
10649            final ApplicationErrorReport.CrashInfo crashInfo) {
10650        // NOTE -- this must never acquire the ActivityManagerService lock,
10651        // otherwise the watchdog may be prevented from resetting the system.
10652
10653        final String dropboxTag = processClass(process) + "_" + eventType;
10654        final DropBoxManager dbox = (DropBoxManager)
10655                mContext.getSystemService(Context.DROPBOX_SERVICE);
10656
10657        // Exit early if the dropbox isn't configured to accept this report type.
10658        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10659
10660        final StringBuilder sb = new StringBuilder(1024);
10661        appendDropBoxProcessHeaders(process, processName, sb);
10662        if (activity != null) {
10663            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10664        }
10665        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10666            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10667        }
10668        if (parent != null && parent != activity) {
10669            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10670        }
10671        if (subject != null) {
10672            sb.append("Subject: ").append(subject).append("\n");
10673        }
10674        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10675        if (Debug.isDebuggerConnected()) {
10676            sb.append("Debugger: Connected\n");
10677        }
10678        sb.append("\n");
10679
10680        // Do the rest in a worker thread to avoid blocking the caller on I/O
10681        // (After this point, we shouldn't access AMS internal data structures.)
10682        Thread worker = new Thread("Error dump: " + dropboxTag) {
10683            @Override
10684            public void run() {
10685                if (report != null) {
10686                    sb.append(report);
10687                }
10688                if (logFile != null) {
10689                    try {
10690                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10691                                    "\n\n[[TRUNCATED]]"));
10692                    } catch (IOException e) {
10693                        Slog.e(TAG, "Error reading " + logFile, e);
10694                    }
10695                }
10696                if (crashInfo != null && crashInfo.stackTrace != null) {
10697                    sb.append(crashInfo.stackTrace);
10698                }
10699
10700                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10701                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10702                if (lines > 0) {
10703                    sb.append("\n");
10704
10705                    // Merge several logcat streams, and take the last N lines
10706                    InputStreamReader input = null;
10707                    try {
10708                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10709                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10710                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10711
10712                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10713                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10714                        input = new InputStreamReader(logcat.getInputStream());
10715
10716                        int num;
10717                        char[] buf = new char[8192];
10718                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10719                    } catch (IOException e) {
10720                        Slog.e(TAG, "Error running logcat", e);
10721                    } finally {
10722                        if (input != null) try { input.close(); } catch (IOException e) {}
10723                    }
10724                }
10725
10726                dbox.addText(dropboxTag, sb.toString());
10727            }
10728        };
10729
10730        if (process == null) {
10731            // If process is null, we are being called from some internal code
10732            // and may be about to die -- run this synchronously.
10733            worker.run();
10734        } else {
10735            worker.start();
10736        }
10737    }
10738
10739    /**
10740     * Bring up the "unexpected error" dialog box for a crashing app.
10741     * Deal with edge cases (intercepts from instrumented applications,
10742     * ActivityController, error intent receivers, that sort of thing).
10743     * @param r the application crashing
10744     * @param crashInfo describing the failure
10745     */
10746    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10747        long timeMillis = System.currentTimeMillis();
10748        String shortMsg = crashInfo.exceptionClassName;
10749        String longMsg = crashInfo.exceptionMessage;
10750        String stackTrace = crashInfo.stackTrace;
10751        if (shortMsg != null && longMsg != null) {
10752            longMsg = shortMsg + ": " + longMsg;
10753        } else if (shortMsg != null) {
10754            longMsg = shortMsg;
10755        }
10756
10757        AppErrorResult result = new AppErrorResult();
10758        synchronized (this) {
10759            if (mController != null) {
10760                try {
10761                    String name = r != null ? r.processName : null;
10762                    int pid = r != null ? r.pid : Binder.getCallingPid();
10763                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
10764                    if (!mController.appCrashed(name, pid,
10765                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10766                        Slog.w(TAG, "Force-killing crashed app " + name
10767                                + " at watcher's request");
10768                        Process.killProcess(pid);
10769                        if (r != null) {
10770                            Process.killProcessGroup(uid, pid);
10771                        }
10772                        return;
10773                    }
10774                } catch (RemoteException e) {
10775                    mController = null;
10776                    Watchdog.getInstance().setActivityController(null);
10777                }
10778            }
10779
10780            final long origId = Binder.clearCallingIdentity();
10781
10782            // If this process is running instrumentation, finish it.
10783            if (r != null && r.instrumentationClass != null) {
10784                Slog.w(TAG, "Error in app " + r.processName
10785                      + " running instrumentation " + r.instrumentationClass + ":");
10786                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10787                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10788                Bundle info = new Bundle();
10789                info.putString("shortMsg", shortMsg);
10790                info.putString("longMsg", longMsg);
10791                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10792                Binder.restoreCallingIdentity(origId);
10793                return;
10794            }
10795
10796            // If we can't identify the process or it's already exceeded its crash quota,
10797            // quit right away without showing a crash dialog.
10798            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10799                Binder.restoreCallingIdentity(origId);
10800                return;
10801            }
10802
10803            Message msg = Message.obtain();
10804            msg.what = SHOW_ERROR_MSG;
10805            HashMap data = new HashMap();
10806            data.put("result", result);
10807            data.put("app", r);
10808            msg.obj = data;
10809            mHandler.sendMessage(msg);
10810
10811            Binder.restoreCallingIdentity(origId);
10812        }
10813
10814        int res = result.get();
10815
10816        Intent appErrorIntent = null;
10817        synchronized (this) {
10818            if (r != null && !r.isolated) {
10819                // XXX Can't keep track of crash time for isolated processes,
10820                // since they don't have a persistent identity.
10821                mProcessCrashTimes.put(r.info.processName, r.uid,
10822                        SystemClock.uptimeMillis());
10823            }
10824            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10825                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10826            }
10827        }
10828
10829        if (appErrorIntent != null) {
10830            try {
10831                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10832            } catch (ActivityNotFoundException e) {
10833                Slog.w(TAG, "bug report receiver dissappeared", e);
10834            }
10835        }
10836    }
10837
10838    Intent createAppErrorIntentLocked(ProcessRecord r,
10839            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10840        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10841        if (report == null) {
10842            return null;
10843        }
10844        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10845        result.setComponent(r.errorReportReceiver);
10846        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10847        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10848        return result;
10849    }
10850
10851    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10852            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10853        if (r.errorReportReceiver == null) {
10854            return null;
10855        }
10856
10857        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10858            return null;
10859        }
10860
10861        ApplicationErrorReport report = new ApplicationErrorReport();
10862        report.packageName = r.info.packageName;
10863        report.installerPackageName = r.errorReportReceiver.getPackageName();
10864        report.processName = r.processName;
10865        report.time = timeMillis;
10866        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10867
10868        if (r.crashing || r.forceCrashReport) {
10869            report.type = ApplicationErrorReport.TYPE_CRASH;
10870            report.crashInfo = crashInfo;
10871        } else if (r.notResponding) {
10872            report.type = ApplicationErrorReport.TYPE_ANR;
10873            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10874
10875            report.anrInfo.activity = r.notRespondingReport.tag;
10876            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10877            report.anrInfo.info = r.notRespondingReport.longMsg;
10878        }
10879
10880        return report;
10881    }
10882
10883    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10884        enforceNotIsolatedCaller("getProcessesInErrorState");
10885        // assume our apps are happy - lazy create the list
10886        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10887
10888        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10889                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10890        int userId = UserHandle.getUserId(Binder.getCallingUid());
10891
10892        synchronized (this) {
10893
10894            // iterate across all processes
10895            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10896                ProcessRecord app = mLruProcesses.get(i);
10897                if (!allUsers && app.userId != userId) {
10898                    continue;
10899                }
10900                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10901                    // This one's in trouble, so we'll generate a report for it
10902                    // crashes are higher priority (in case there's a crash *and* an anr)
10903                    ActivityManager.ProcessErrorStateInfo report = null;
10904                    if (app.crashing) {
10905                        report = app.crashingReport;
10906                    } else if (app.notResponding) {
10907                        report = app.notRespondingReport;
10908                    }
10909
10910                    if (report != null) {
10911                        if (errList == null) {
10912                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10913                        }
10914                        errList.add(report);
10915                    } else {
10916                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10917                                " crashing = " + app.crashing +
10918                                " notResponding = " + app.notResponding);
10919                    }
10920                }
10921            }
10922        }
10923
10924        return errList;
10925    }
10926
10927    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10928        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10929            if (currApp != null) {
10930                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10931            }
10932            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10933        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10934            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10935        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10936            if (currApp != null) {
10937                currApp.lru = 0;
10938            }
10939            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10940        } else if (adj >= ProcessList.SERVICE_ADJ) {
10941            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10942        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10943            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10944        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10945            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10946        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10947            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10948        } else {
10949            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10950        }
10951    }
10952
10953    private void fillInProcMemInfo(ProcessRecord app,
10954            ActivityManager.RunningAppProcessInfo outInfo) {
10955        outInfo.pid = app.pid;
10956        outInfo.uid = app.info.uid;
10957        if (mHeavyWeightProcess == app) {
10958            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10959        }
10960        if (app.persistent) {
10961            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10962        }
10963        if (app.activities.size() > 0) {
10964            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10965        }
10966        outInfo.lastTrimLevel = app.trimMemoryLevel;
10967        int adj = app.curAdj;
10968        outInfo.importance = oomAdjToImportance(adj, outInfo);
10969        outInfo.importanceReasonCode = app.adjTypeCode;
10970        outInfo.processState = app.curProcState;
10971    }
10972
10973    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10974        enforceNotIsolatedCaller("getRunningAppProcesses");
10975        // Lazy instantiation of list
10976        List<ActivityManager.RunningAppProcessInfo> runList = null;
10977        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10978                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10979        int userId = UserHandle.getUserId(Binder.getCallingUid());
10980        synchronized (this) {
10981            // Iterate across all processes
10982            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10983                ProcessRecord app = mLruProcesses.get(i);
10984                if (!allUsers && app.userId != userId) {
10985                    continue;
10986                }
10987                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10988                    // Generate process state info for running application
10989                    ActivityManager.RunningAppProcessInfo currApp =
10990                        new ActivityManager.RunningAppProcessInfo(app.processName,
10991                                app.pid, app.getPackageList());
10992                    fillInProcMemInfo(app, currApp);
10993                    if (app.adjSource instanceof ProcessRecord) {
10994                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10995                        currApp.importanceReasonImportance = oomAdjToImportance(
10996                                app.adjSourceOom, null);
10997                    } else if (app.adjSource instanceof ActivityRecord) {
10998                        ActivityRecord r = (ActivityRecord)app.adjSource;
10999                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11000                    }
11001                    if (app.adjTarget instanceof ComponentName) {
11002                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11003                    }
11004                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11005                    //        + " lru=" + currApp.lru);
11006                    if (runList == null) {
11007                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11008                    }
11009                    runList.add(currApp);
11010                }
11011            }
11012        }
11013        return runList;
11014    }
11015
11016    public List<ApplicationInfo> getRunningExternalApplications() {
11017        enforceNotIsolatedCaller("getRunningExternalApplications");
11018        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11019        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11020        if (runningApps != null && runningApps.size() > 0) {
11021            Set<String> extList = new HashSet<String>();
11022            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11023                if (app.pkgList != null) {
11024                    for (String pkg : app.pkgList) {
11025                        extList.add(pkg);
11026                    }
11027                }
11028            }
11029            IPackageManager pm = AppGlobals.getPackageManager();
11030            for (String pkg : extList) {
11031                try {
11032                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11033                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11034                        retList.add(info);
11035                    }
11036                } catch (RemoteException e) {
11037                }
11038            }
11039        }
11040        return retList;
11041    }
11042
11043    @Override
11044    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11045        enforceNotIsolatedCaller("getMyMemoryState");
11046        synchronized (this) {
11047            ProcessRecord proc;
11048            synchronized (mPidsSelfLocked) {
11049                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11050            }
11051            fillInProcMemInfo(proc, outInfo);
11052        }
11053    }
11054
11055    @Override
11056    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11057        if (checkCallingPermission(android.Manifest.permission.DUMP)
11058                != PackageManager.PERMISSION_GRANTED) {
11059            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11060                    + Binder.getCallingPid()
11061                    + ", uid=" + Binder.getCallingUid()
11062                    + " without permission "
11063                    + android.Manifest.permission.DUMP);
11064            return;
11065        }
11066
11067        boolean dumpAll = false;
11068        boolean dumpClient = false;
11069        String dumpPackage = null;
11070
11071        int opti = 0;
11072        while (opti < args.length) {
11073            String opt = args[opti];
11074            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11075                break;
11076            }
11077            opti++;
11078            if ("-a".equals(opt)) {
11079                dumpAll = true;
11080            } else if ("-c".equals(opt)) {
11081                dumpClient = true;
11082            } else if ("-h".equals(opt)) {
11083                pw.println("Activity manager dump options:");
11084                pw.println("  [-a] [-c] [-h] [cmd] ...");
11085                pw.println("  cmd may be one of:");
11086                pw.println("    a[ctivities]: activity stack state");
11087                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11088                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11089                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11090                pw.println("    o[om]: out of memory management");
11091                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11092                pw.println("    provider [COMP_SPEC]: provider client-side state");
11093                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11094                pw.println("    service [COMP_SPEC]: service client-side state");
11095                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11096                pw.println("    all: dump all activities");
11097                pw.println("    top: dump the top activity");
11098                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11099                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11100                pw.println("    a partial substring in a component name, a");
11101                pw.println("    hex object identifier.");
11102                pw.println("  -a: include all available server state.");
11103                pw.println("  -c: include client state.");
11104                return;
11105            } else {
11106                pw.println("Unknown argument: " + opt + "; use -h for help");
11107            }
11108        }
11109
11110        long origId = Binder.clearCallingIdentity();
11111        boolean more = false;
11112        // Is the caller requesting to dump a particular piece of data?
11113        if (opti < args.length) {
11114            String cmd = args[opti];
11115            opti++;
11116            if ("activities".equals(cmd) || "a".equals(cmd)) {
11117                synchronized (this) {
11118                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11119                }
11120            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11121                String[] newArgs;
11122                String name;
11123                if (opti >= args.length) {
11124                    name = null;
11125                    newArgs = EMPTY_STRING_ARRAY;
11126                } else {
11127                    name = args[opti];
11128                    opti++;
11129                    newArgs = new String[args.length - opti];
11130                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11131                            args.length - opti);
11132                }
11133                synchronized (this) {
11134                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11135                }
11136            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11137                String[] newArgs;
11138                String name;
11139                if (opti >= args.length) {
11140                    name = null;
11141                    newArgs = EMPTY_STRING_ARRAY;
11142                } else {
11143                    name = args[opti];
11144                    opti++;
11145                    newArgs = new String[args.length - opti];
11146                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11147                            args.length - opti);
11148                }
11149                synchronized (this) {
11150                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11151                }
11152            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11153                String[] newArgs;
11154                String name;
11155                if (opti >= args.length) {
11156                    name = null;
11157                    newArgs = EMPTY_STRING_ARRAY;
11158                } else {
11159                    name = args[opti];
11160                    opti++;
11161                    newArgs = new String[args.length - opti];
11162                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11163                            args.length - opti);
11164                }
11165                synchronized (this) {
11166                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11167                }
11168            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11169                synchronized (this) {
11170                    dumpOomLocked(fd, pw, args, opti, true);
11171                }
11172            } else if ("provider".equals(cmd)) {
11173                String[] newArgs;
11174                String name;
11175                if (opti >= args.length) {
11176                    name = null;
11177                    newArgs = EMPTY_STRING_ARRAY;
11178                } else {
11179                    name = args[opti];
11180                    opti++;
11181                    newArgs = new String[args.length - opti];
11182                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11183                }
11184                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11185                    pw.println("No providers match: " + name);
11186                    pw.println("Use -h for help.");
11187                }
11188            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11189                synchronized (this) {
11190                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11191                }
11192            } else if ("service".equals(cmd)) {
11193                String[] newArgs;
11194                String name;
11195                if (opti >= args.length) {
11196                    name = null;
11197                    newArgs = EMPTY_STRING_ARRAY;
11198                } else {
11199                    name = args[opti];
11200                    opti++;
11201                    newArgs = new String[args.length - opti];
11202                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11203                            args.length - opti);
11204                }
11205                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11206                    pw.println("No services match: " + name);
11207                    pw.println("Use -h for help.");
11208                }
11209            } else if ("package".equals(cmd)) {
11210                String[] newArgs;
11211                if (opti >= args.length) {
11212                    pw.println("package: no package name specified");
11213                    pw.println("Use -h for help.");
11214                } else {
11215                    dumpPackage = args[opti];
11216                    opti++;
11217                    newArgs = new String[args.length - opti];
11218                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11219                            args.length - opti);
11220                    args = newArgs;
11221                    opti = 0;
11222                    more = true;
11223                }
11224            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11225                synchronized (this) {
11226                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11227                }
11228            } else {
11229                // Dumping a single activity?
11230                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11231                    pw.println("Bad activity command, or no activities match: " + cmd);
11232                    pw.println("Use -h for help.");
11233                }
11234            }
11235            if (!more) {
11236                Binder.restoreCallingIdentity(origId);
11237                return;
11238            }
11239        }
11240
11241        // No piece of data specified, dump everything.
11242        synchronized (this) {
11243            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11244            pw.println();
11245            if (dumpAll) {
11246                pw.println("-------------------------------------------------------------------------------");
11247            }
11248            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11249            pw.println();
11250            if (dumpAll) {
11251                pw.println("-------------------------------------------------------------------------------");
11252            }
11253            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11254            pw.println();
11255            if (dumpAll) {
11256                pw.println("-------------------------------------------------------------------------------");
11257            }
11258            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11259            pw.println();
11260            if (dumpAll) {
11261                pw.println("-------------------------------------------------------------------------------");
11262            }
11263            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11264            pw.println();
11265            if (dumpAll) {
11266                pw.println("-------------------------------------------------------------------------------");
11267            }
11268            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11269        }
11270        Binder.restoreCallingIdentity(origId);
11271    }
11272
11273    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11274            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11275        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11276
11277        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11278                dumpPackage);
11279        boolean needSep = printedAnything;
11280
11281        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11282                dumpPackage, needSep, "  mFocusedActivity: ");
11283        if (printed) {
11284            printedAnything = true;
11285            needSep = false;
11286        }
11287
11288        if (dumpPackage == null) {
11289            if (needSep) {
11290                pw.println();
11291            }
11292            needSep = true;
11293            printedAnything = true;
11294            mStackSupervisor.dump(pw, "  ");
11295        }
11296
11297        if (mRecentTasks.size() > 0) {
11298            boolean printedHeader = false;
11299
11300            final int N = mRecentTasks.size();
11301            for (int i=0; i<N; i++) {
11302                TaskRecord tr = mRecentTasks.get(i);
11303                if (dumpPackage != null) {
11304                    if (tr.realActivity == null ||
11305                            !dumpPackage.equals(tr.realActivity)) {
11306                        continue;
11307                    }
11308                }
11309                if (!printedHeader) {
11310                    if (needSep) {
11311                        pw.println();
11312                    }
11313                    pw.println("  Recent tasks:");
11314                    printedHeader = true;
11315                    printedAnything = true;
11316                }
11317                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11318                        pw.println(tr);
11319                if (dumpAll) {
11320                    mRecentTasks.get(i).dump(pw, "    ");
11321                }
11322            }
11323        }
11324
11325        if (!printedAnything) {
11326            pw.println("  (nothing)");
11327        }
11328    }
11329
11330    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11331            int opti, boolean dumpAll, String dumpPackage) {
11332        boolean needSep = false;
11333        boolean printedAnything = false;
11334        int numPers = 0;
11335
11336        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11337
11338        if (dumpAll) {
11339            final int NP = mProcessNames.getMap().size();
11340            for (int ip=0; ip<NP; ip++) {
11341                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11342                final int NA = procs.size();
11343                for (int ia=0; ia<NA; ia++) {
11344                    ProcessRecord r = procs.valueAt(ia);
11345                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11346                        continue;
11347                    }
11348                    if (!needSep) {
11349                        pw.println("  All known processes:");
11350                        needSep = true;
11351                        printedAnything = true;
11352                    }
11353                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11354                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11355                        pw.print(" "); pw.println(r);
11356                    r.dump(pw, "    ");
11357                    if (r.persistent) {
11358                        numPers++;
11359                    }
11360                }
11361            }
11362        }
11363
11364        if (mIsolatedProcesses.size() > 0) {
11365            boolean printed = false;
11366            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11367                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11368                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11369                    continue;
11370                }
11371                if (!printed) {
11372                    if (needSep) {
11373                        pw.println();
11374                    }
11375                    pw.println("  Isolated process list (sorted by uid):");
11376                    printedAnything = true;
11377                    printed = true;
11378                    needSep = true;
11379                }
11380                pw.println(String.format("%sIsolated #%2d: %s",
11381                        "    ", i, r.toString()));
11382            }
11383        }
11384
11385        if (mLruProcesses.size() > 0) {
11386            if (needSep) {
11387                pw.println();
11388            }
11389            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11390                    pw.print(" total, non-act at ");
11391                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11392                    pw.print(", non-svc at ");
11393                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11394                    pw.println("):");
11395            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11396            needSep = true;
11397            printedAnything = true;
11398        }
11399
11400        if (dumpAll || dumpPackage != null) {
11401            synchronized (mPidsSelfLocked) {
11402                boolean printed = false;
11403                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11404                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11405                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11406                        continue;
11407                    }
11408                    if (!printed) {
11409                        if (needSep) pw.println();
11410                        needSep = true;
11411                        pw.println("  PID mappings:");
11412                        printed = true;
11413                        printedAnything = true;
11414                    }
11415                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11416                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11417                }
11418            }
11419        }
11420
11421        if (mForegroundProcesses.size() > 0) {
11422            synchronized (mPidsSelfLocked) {
11423                boolean printed = false;
11424                for (int i=0; i<mForegroundProcesses.size(); i++) {
11425                    ProcessRecord r = mPidsSelfLocked.get(
11426                            mForegroundProcesses.valueAt(i).pid);
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("  Foreground Processes:");
11435                        printed = true;
11436                        printedAnything = true;
11437                    }
11438                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11439                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11440                }
11441            }
11442        }
11443
11444        if (mPersistentStartingProcesses.size() > 0) {
11445            if (needSep) pw.println();
11446            needSep = true;
11447            printedAnything = true;
11448            pw.println("  Persisent processes that are starting:");
11449            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11450                    "Starting Norm", "Restarting PERS", dumpPackage);
11451        }
11452
11453        if (mRemovedProcesses.size() > 0) {
11454            if (needSep) pw.println();
11455            needSep = true;
11456            printedAnything = true;
11457            pw.println("  Processes that are being removed:");
11458            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11459                    "Removed Norm", "Removed PERS", dumpPackage);
11460        }
11461
11462        if (mProcessesOnHold.size() > 0) {
11463            if (needSep) pw.println();
11464            needSep = true;
11465            printedAnything = true;
11466            pw.println("  Processes that are on old until the system is ready:");
11467            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11468                    "OnHold Norm", "OnHold PERS", dumpPackage);
11469        }
11470
11471        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11472
11473        if (mProcessCrashTimes.getMap().size() > 0) {
11474            boolean printed = false;
11475            long now = SystemClock.uptimeMillis();
11476            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11477            final int NP = pmap.size();
11478            for (int ip=0; ip<NP; ip++) {
11479                String pname = pmap.keyAt(ip);
11480                SparseArray<Long> uids = pmap.valueAt(ip);
11481                final int N = uids.size();
11482                for (int i=0; i<N; i++) {
11483                    int puid = uids.keyAt(i);
11484                    ProcessRecord r = mProcessNames.get(pname, puid);
11485                    if (dumpPackage != null && (r == null
11486                            || !r.pkgList.containsKey(dumpPackage))) {
11487                        continue;
11488                    }
11489                    if (!printed) {
11490                        if (needSep) pw.println();
11491                        needSep = true;
11492                        pw.println("  Time since processes crashed:");
11493                        printed = true;
11494                        printedAnything = true;
11495                    }
11496                    pw.print("    Process "); pw.print(pname);
11497                            pw.print(" uid "); pw.print(puid);
11498                            pw.print(": last crashed ");
11499                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11500                            pw.println(" ago");
11501                }
11502            }
11503        }
11504
11505        if (mBadProcesses.getMap().size() > 0) {
11506            boolean printed = false;
11507            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11508            final int NP = pmap.size();
11509            for (int ip=0; ip<NP; ip++) {
11510                String pname = pmap.keyAt(ip);
11511                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11512                final int N = uids.size();
11513                for (int i=0; i<N; i++) {
11514                    int puid = uids.keyAt(i);
11515                    ProcessRecord r = mProcessNames.get(pname, puid);
11516                    if (dumpPackage != null && (r == null
11517                            || !r.pkgList.containsKey(dumpPackage))) {
11518                        continue;
11519                    }
11520                    if (!printed) {
11521                        if (needSep) pw.println();
11522                        needSep = true;
11523                        pw.println("  Bad processes:");
11524                        printedAnything = true;
11525                    }
11526                    BadProcessInfo info = uids.valueAt(i);
11527                    pw.print("    Bad process "); pw.print(pname);
11528                            pw.print(" uid "); pw.print(puid);
11529                            pw.print(": crashed at time "); pw.println(info.time);
11530                    if (info.shortMsg != null) {
11531                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11532                    }
11533                    if (info.longMsg != null) {
11534                        pw.print("      Long msg: "); pw.println(info.longMsg);
11535                    }
11536                    if (info.stack != null) {
11537                        pw.println("      Stack:");
11538                        int lastPos = 0;
11539                        for (int pos=0; pos<info.stack.length(); pos++) {
11540                            if (info.stack.charAt(pos) == '\n') {
11541                                pw.print("        ");
11542                                pw.write(info.stack, lastPos, pos-lastPos);
11543                                pw.println();
11544                                lastPos = pos+1;
11545                            }
11546                        }
11547                        if (lastPos < info.stack.length()) {
11548                            pw.print("        ");
11549                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11550                            pw.println();
11551                        }
11552                    }
11553                }
11554            }
11555        }
11556
11557        if (dumpPackage == null) {
11558            pw.println();
11559            needSep = false;
11560            pw.println("  mStartedUsers:");
11561            for (int i=0; i<mStartedUsers.size(); i++) {
11562                UserStartedState uss = mStartedUsers.valueAt(i);
11563                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11564                        pw.print(": "); uss.dump("", pw);
11565            }
11566            pw.print("  mStartedUserArray: [");
11567            for (int i=0; i<mStartedUserArray.length; i++) {
11568                if (i > 0) pw.print(", ");
11569                pw.print(mStartedUserArray[i]);
11570            }
11571            pw.println("]");
11572            pw.print("  mUserLru: [");
11573            for (int i=0; i<mUserLru.size(); i++) {
11574                if (i > 0) pw.print(", ");
11575                pw.print(mUserLru.get(i));
11576            }
11577            pw.println("]");
11578            if (dumpAll) {
11579                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11580            }
11581        }
11582        if (mHomeProcess != null && (dumpPackage == null
11583                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11584            if (needSep) {
11585                pw.println();
11586                needSep = false;
11587            }
11588            pw.println("  mHomeProcess: " + mHomeProcess);
11589        }
11590        if (mPreviousProcess != null && (dumpPackage == null
11591                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11592            if (needSep) {
11593                pw.println();
11594                needSep = false;
11595            }
11596            pw.println("  mPreviousProcess: " + mPreviousProcess);
11597        }
11598        if (dumpAll) {
11599            StringBuilder sb = new StringBuilder(128);
11600            sb.append("  mPreviousProcessVisibleTime: ");
11601            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11602            pw.println(sb);
11603        }
11604        if (mHeavyWeightProcess != null && (dumpPackage == null
11605                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11606            if (needSep) {
11607                pw.println();
11608                needSep = false;
11609            }
11610            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11611        }
11612        if (dumpPackage == null) {
11613            pw.println("  mConfiguration: " + mConfiguration);
11614        }
11615        if (dumpAll) {
11616            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11617            if (mCompatModePackages.getPackages().size() > 0) {
11618                boolean printed = false;
11619                for (Map.Entry<String, Integer> entry
11620                        : mCompatModePackages.getPackages().entrySet()) {
11621                    String pkg = entry.getKey();
11622                    int mode = entry.getValue();
11623                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11624                        continue;
11625                    }
11626                    if (!printed) {
11627                        pw.println("  mScreenCompatPackages:");
11628                        printed = true;
11629                    }
11630                    pw.print("    "); pw.print(pkg); pw.print(": ");
11631                            pw.print(mode); pw.println();
11632                }
11633            }
11634        }
11635        if (dumpPackage == null) {
11636            if (mSleeping || mWentToSleep || mLockScreenShown) {
11637                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11638                        + " mLockScreenShown " + mLockScreenShown);
11639            }
11640            if (mShuttingDown || mRunningVoice) {
11641                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11642            }
11643        }
11644        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11645                || mOrigWaitForDebugger) {
11646            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11647                    || dumpPackage.equals(mOrigDebugApp)) {
11648                if (needSep) {
11649                    pw.println();
11650                    needSep = false;
11651                }
11652                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11653                        + " mDebugTransient=" + mDebugTransient
11654                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11655            }
11656        }
11657        if (mOpenGlTraceApp != null) {
11658            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11659                if (needSep) {
11660                    pw.println();
11661                    needSep = false;
11662                }
11663                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11664            }
11665        }
11666        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11667                || mProfileFd != null) {
11668            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11669                if (needSep) {
11670                    pw.println();
11671                    needSep = false;
11672                }
11673                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11674                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11675                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11676                        + mAutoStopProfiler);
11677            }
11678        }
11679        if (dumpPackage == null) {
11680            if (mAlwaysFinishActivities || mController != null) {
11681                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11682                        + " mController=" + mController);
11683            }
11684            if (dumpAll) {
11685                pw.println("  Total persistent processes: " + numPers);
11686                pw.println("  mProcessesReady=" + mProcessesReady
11687                        + " mSystemReady=" + mSystemReady);
11688                pw.println("  mBooting=" + mBooting
11689                        + " mBooted=" + mBooted
11690                        + " mFactoryTest=" + mFactoryTest);
11691                pw.print("  mLastPowerCheckRealtime=");
11692                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11693                        pw.println("");
11694                pw.print("  mLastPowerCheckUptime=");
11695                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11696                        pw.println("");
11697                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11698                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11699                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11700                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11701                        + " (" + mLruProcesses.size() + " total)"
11702                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11703                        + " mNumServiceProcs=" + mNumServiceProcs
11704                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11705                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11706                        + " mLastMemoryLevel" + mLastMemoryLevel
11707                        + " mLastNumProcesses" + mLastNumProcesses);
11708                long now = SystemClock.uptimeMillis();
11709                pw.print("  mLastIdleTime=");
11710                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11711                        pw.print(" mLowRamSinceLastIdle=");
11712                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11713                        pw.println();
11714            }
11715        }
11716
11717        if (!printedAnything) {
11718            pw.println("  (nothing)");
11719        }
11720    }
11721
11722    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11723            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11724        if (mProcessesToGc.size() > 0) {
11725            boolean printed = false;
11726            long now = SystemClock.uptimeMillis();
11727            for (int i=0; i<mProcessesToGc.size(); i++) {
11728                ProcessRecord proc = mProcessesToGc.get(i);
11729                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11730                    continue;
11731                }
11732                if (!printed) {
11733                    if (needSep) pw.println();
11734                    needSep = true;
11735                    pw.println("  Processes that are waiting to GC:");
11736                    printed = true;
11737                }
11738                pw.print("    Process "); pw.println(proc);
11739                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11740                        pw.print(", last gced=");
11741                        pw.print(now-proc.lastRequestedGc);
11742                        pw.print(" ms ago, last lowMem=");
11743                        pw.print(now-proc.lastLowMemory);
11744                        pw.println(" ms ago");
11745
11746            }
11747        }
11748        return needSep;
11749    }
11750
11751    void printOomLevel(PrintWriter pw, String name, int adj) {
11752        pw.print("    ");
11753        if (adj >= 0) {
11754            pw.print(' ');
11755            if (adj < 10) pw.print(' ');
11756        } else {
11757            if (adj > -10) pw.print(' ');
11758        }
11759        pw.print(adj);
11760        pw.print(": ");
11761        pw.print(name);
11762        pw.print(" (");
11763        pw.print(mProcessList.getMemLevel(adj)/1024);
11764        pw.println(" kB)");
11765    }
11766
11767    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11768            int opti, boolean dumpAll) {
11769        boolean needSep = false;
11770
11771        if (mLruProcesses.size() > 0) {
11772            if (needSep) pw.println();
11773            needSep = true;
11774            pw.println("  OOM levels:");
11775            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11776            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11777            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11778            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11779            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11780            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11781            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11782            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11783            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11784            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11785            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11786            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11787            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11788
11789            if (needSep) pw.println();
11790            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11791                    pw.print(" total, non-act at ");
11792                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11793                    pw.print(", non-svc at ");
11794                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11795                    pw.println("):");
11796            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11797            needSep = true;
11798        }
11799
11800        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11801
11802        pw.println();
11803        pw.println("  mHomeProcess: " + mHomeProcess);
11804        pw.println("  mPreviousProcess: " + mPreviousProcess);
11805        if (mHeavyWeightProcess != null) {
11806            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11807        }
11808
11809        return true;
11810    }
11811
11812    /**
11813     * There are three ways to call this:
11814     *  - no provider specified: dump all the providers
11815     *  - a flattened component name that matched an existing provider was specified as the
11816     *    first arg: dump that one provider
11817     *  - the first arg isn't the flattened component name of an existing provider:
11818     *    dump all providers whose component contains the first arg as a substring
11819     */
11820    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11821            int opti, boolean dumpAll) {
11822        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11823    }
11824
11825    static class ItemMatcher {
11826        ArrayList<ComponentName> components;
11827        ArrayList<String> strings;
11828        ArrayList<Integer> objects;
11829        boolean all;
11830
11831        ItemMatcher() {
11832            all = true;
11833        }
11834
11835        void build(String name) {
11836            ComponentName componentName = ComponentName.unflattenFromString(name);
11837            if (componentName != null) {
11838                if (components == null) {
11839                    components = new ArrayList<ComponentName>();
11840                }
11841                components.add(componentName);
11842                all = false;
11843            } else {
11844                int objectId = 0;
11845                // Not a '/' separated full component name; maybe an object ID?
11846                try {
11847                    objectId = Integer.parseInt(name, 16);
11848                    if (objects == null) {
11849                        objects = new ArrayList<Integer>();
11850                    }
11851                    objects.add(objectId);
11852                    all = false;
11853                } catch (RuntimeException e) {
11854                    // Not an integer; just do string match.
11855                    if (strings == null) {
11856                        strings = new ArrayList<String>();
11857                    }
11858                    strings.add(name);
11859                    all = false;
11860                }
11861            }
11862        }
11863
11864        int build(String[] args, int opti) {
11865            for (; opti<args.length; opti++) {
11866                String name = args[opti];
11867                if ("--".equals(name)) {
11868                    return opti+1;
11869                }
11870                build(name);
11871            }
11872            return opti;
11873        }
11874
11875        boolean match(Object object, ComponentName comp) {
11876            if (all) {
11877                return true;
11878            }
11879            if (components != null) {
11880                for (int i=0; i<components.size(); i++) {
11881                    if (components.get(i).equals(comp)) {
11882                        return true;
11883                    }
11884                }
11885            }
11886            if (objects != null) {
11887                for (int i=0; i<objects.size(); i++) {
11888                    if (System.identityHashCode(object) == objects.get(i)) {
11889                        return true;
11890                    }
11891                }
11892            }
11893            if (strings != null) {
11894                String flat = comp.flattenToString();
11895                for (int i=0; i<strings.size(); i++) {
11896                    if (flat.contains(strings.get(i))) {
11897                        return true;
11898                    }
11899                }
11900            }
11901            return false;
11902        }
11903    }
11904
11905    /**
11906     * There are three things that cmd can be:
11907     *  - a flattened component name that matches an existing activity
11908     *  - the cmd arg isn't the flattened component name of an existing activity:
11909     *    dump all activity whose component contains the cmd as a substring
11910     *  - A hex number of the ActivityRecord object instance.
11911     */
11912    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11913            int opti, boolean dumpAll) {
11914        ArrayList<ActivityRecord> activities;
11915
11916        synchronized (this) {
11917            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11918        }
11919
11920        if (activities.size() <= 0) {
11921            return false;
11922        }
11923
11924        String[] newArgs = new String[args.length - opti];
11925        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11926
11927        TaskRecord lastTask = null;
11928        boolean needSep = false;
11929        for (int i=activities.size()-1; i>=0; i--) {
11930            ActivityRecord r = activities.get(i);
11931            if (needSep) {
11932                pw.println();
11933            }
11934            needSep = true;
11935            synchronized (this) {
11936                if (lastTask != r.task) {
11937                    lastTask = r.task;
11938                    pw.print("TASK "); pw.print(lastTask.affinity);
11939                            pw.print(" id="); pw.println(lastTask.taskId);
11940                    if (dumpAll) {
11941                        lastTask.dump(pw, "  ");
11942                    }
11943                }
11944            }
11945            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11946        }
11947        return true;
11948    }
11949
11950    /**
11951     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11952     * there is a thread associated with the activity.
11953     */
11954    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11955            final ActivityRecord r, String[] args, boolean dumpAll) {
11956        String innerPrefix = prefix + "  ";
11957        synchronized (this) {
11958            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11959                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11960                    pw.print(" pid=");
11961                    if (r.app != null) pw.println(r.app.pid);
11962                    else pw.println("(not running)");
11963            if (dumpAll) {
11964                r.dump(pw, innerPrefix);
11965            }
11966        }
11967        if (r.app != null && r.app.thread != null) {
11968            // flush anything that is already in the PrintWriter since the thread is going
11969            // to write to the file descriptor directly
11970            pw.flush();
11971            try {
11972                TransferPipe tp = new TransferPipe();
11973                try {
11974                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11975                            r.appToken, innerPrefix, args);
11976                    tp.go(fd);
11977                } finally {
11978                    tp.kill();
11979                }
11980            } catch (IOException e) {
11981                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11982            } catch (RemoteException e) {
11983                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11984            }
11985        }
11986    }
11987
11988    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11989            int opti, boolean dumpAll, String dumpPackage) {
11990        boolean needSep = false;
11991        boolean onlyHistory = false;
11992        boolean printedAnything = false;
11993
11994        if ("history".equals(dumpPackage)) {
11995            if (opti < args.length && "-s".equals(args[opti])) {
11996                dumpAll = false;
11997            }
11998            onlyHistory = true;
11999            dumpPackage = null;
12000        }
12001
12002        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12003        if (!onlyHistory && dumpAll) {
12004            if (mRegisteredReceivers.size() > 0) {
12005                boolean printed = false;
12006                Iterator it = mRegisteredReceivers.values().iterator();
12007                while (it.hasNext()) {
12008                    ReceiverList r = (ReceiverList)it.next();
12009                    if (dumpPackage != null && (r.app == null ||
12010                            !dumpPackage.equals(r.app.info.packageName))) {
12011                        continue;
12012                    }
12013                    if (!printed) {
12014                        pw.println("  Registered Receivers:");
12015                        needSep = true;
12016                        printed = true;
12017                        printedAnything = true;
12018                    }
12019                    pw.print("  * "); pw.println(r);
12020                    r.dump(pw, "    ");
12021                }
12022            }
12023
12024            if (mReceiverResolver.dump(pw, needSep ?
12025                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12026                    "    ", dumpPackage, false)) {
12027                needSep = true;
12028                printedAnything = true;
12029            }
12030        }
12031
12032        for (BroadcastQueue q : mBroadcastQueues) {
12033            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12034            printedAnything |= needSep;
12035        }
12036
12037        needSep = true;
12038
12039        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12040            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12041                if (needSep) {
12042                    pw.println();
12043                }
12044                needSep = true;
12045                printedAnything = true;
12046                pw.print("  Sticky broadcasts for user ");
12047                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12048                StringBuilder sb = new StringBuilder(128);
12049                for (Map.Entry<String, ArrayList<Intent>> ent
12050                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12051                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12052                    if (dumpAll) {
12053                        pw.println(":");
12054                        ArrayList<Intent> intents = ent.getValue();
12055                        final int N = intents.size();
12056                        for (int i=0; i<N; i++) {
12057                            sb.setLength(0);
12058                            sb.append("    Intent: ");
12059                            intents.get(i).toShortString(sb, false, true, false, false);
12060                            pw.println(sb.toString());
12061                            Bundle bundle = intents.get(i).getExtras();
12062                            if (bundle != null) {
12063                                pw.print("      ");
12064                                pw.println(bundle.toString());
12065                            }
12066                        }
12067                    } else {
12068                        pw.println("");
12069                    }
12070                }
12071            }
12072        }
12073
12074        if (!onlyHistory && dumpAll) {
12075            pw.println();
12076            for (BroadcastQueue queue : mBroadcastQueues) {
12077                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12078                        + queue.mBroadcastsScheduled);
12079            }
12080            pw.println("  mHandler:");
12081            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12082            needSep = true;
12083            printedAnything = true;
12084        }
12085
12086        if (!printedAnything) {
12087            pw.println("  (nothing)");
12088        }
12089    }
12090
12091    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12092            int opti, boolean dumpAll, String dumpPackage) {
12093        boolean needSep;
12094        boolean printedAnything = false;
12095
12096        ItemMatcher matcher = new ItemMatcher();
12097        matcher.build(args, opti);
12098
12099        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12100
12101        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12102        printedAnything |= needSep;
12103
12104        if (mLaunchingProviders.size() > 0) {
12105            boolean printed = false;
12106            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12107                ContentProviderRecord r = mLaunchingProviders.get(i);
12108                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12109                    continue;
12110                }
12111                if (!printed) {
12112                    if (needSep) pw.println();
12113                    needSep = true;
12114                    pw.println("  Launching content providers:");
12115                    printed = true;
12116                    printedAnything = true;
12117                }
12118                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12119                        pw.println(r);
12120            }
12121        }
12122
12123        if (mGrantedUriPermissions.size() > 0) {
12124            boolean printed = false;
12125            int dumpUid = -2;
12126            if (dumpPackage != null) {
12127                try {
12128                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12129                } catch (NameNotFoundException e) {
12130                    dumpUid = -1;
12131                }
12132            }
12133            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12134                int uid = mGrantedUriPermissions.keyAt(i);
12135                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12136                    continue;
12137                }
12138                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12139                if (!printed) {
12140                    if (needSep) pw.println();
12141                    needSep = true;
12142                    pw.println("  Granted Uri Permissions:");
12143                    printed = true;
12144                    printedAnything = true;
12145                }
12146                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12147                for (UriPermission perm : perms.values()) {
12148                    pw.print("    "); pw.println(perm);
12149                    if (dumpAll) {
12150                        perm.dump(pw, "      ");
12151                    }
12152                }
12153            }
12154        }
12155
12156        if (!printedAnything) {
12157            pw.println("  (nothing)");
12158        }
12159    }
12160
12161    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12162            int opti, boolean dumpAll, String dumpPackage) {
12163        boolean printed = false;
12164
12165        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12166
12167        if (mIntentSenderRecords.size() > 0) {
12168            Iterator<WeakReference<PendingIntentRecord>> it
12169                    = mIntentSenderRecords.values().iterator();
12170            while (it.hasNext()) {
12171                WeakReference<PendingIntentRecord> ref = it.next();
12172                PendingIntentRecord rec = ref != null ? ref.get(): null;
12173                if (dumpPackage != null && (rec == null
12174                        || !dumpPackage.equals(rec.key.packageName))) {
12175                    continue;
12176                }
12177                printed = true;
12178                if (rec != null) {
12179                    pw.print("  * "); pw.println(rec);
12180                    if (dumpAll) {
12181                        rec.dump(pw, "    ");
12182                    }
12183                } else {
12184                    pw.print("  * "); pw.println(ref);
12185                }
12186            }
12187        }
12188
12189        if (!printed) {
12190            pw.println("  (nothing)");
12191        }
12192    }
12193
12194    private static final int dumpProcessList(PrintWriter pw,
12195            ActivityManagerService service, List list,
12196            String prefix, String normalLabel, String persistentLabel,
12197            String dumpPackage) {
12198        int numPers = 0;
12199        final int N = list.size()-1;
12200        for (int i=N; i>=0; i--) {
12201            ProcessRecord r = (ProcessRecord)list.get(i);
12202            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12203                continue;
12204            }
12205            pw.println(String.format("%s%s #%2d: %s",
12206                    prefix, (r.persistent ? persistentLabel : normalLabel),
12207                    i, r.toString()));
12208            if (r.persistent) {
12209                numPers++;
12210            }
12211        }
12212        return numPers;
12213    }
12214
12215    private static final boolean dumpProcessOomList(PrintWriter pw,
12216            ActivityManagerService service, List<ProcessRecord> origList,
12217            String prefix, String normalLabel, String persistentLabel,
12218            boolean inclDetails, String dumpPackage) {
12219
12220        ArrayList<Pair<ProcessRecord, Integer>> list
12221                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12222        for (int i=0; i<origList.size(); i++) {
12223            ProcessRecord r = origList.get(i);
12224            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12225                continue;
12226            }
12227            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12228        }
12229
12230        if (list.size() <= 0) {
12231            return false;
12232        }
12233
12234        Comparator<Pair<ProcessRecord, Integer>> comparator
12235                = new Comparator<Pair<ProcessRecord, Integer>>() {
12236            @Override
12237            public int compare(Pair<ProcessRecord, Integer> object1,
12238                    Pair<ProcessRecord, Integer> object2) {
12239                if (object1.first.setAdj != object2.first.setAdj) {
12240                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12241                }
12242                if (object1.second.intValue() != object2.second.intValue()) {
12243                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12244                }
12245                return 0;
12246            }
12247        };
12248
12249        Collections.sort(list, comparator);
12250
12251        final long curRealtime = SystemClock.elapsedRealtime();
12252        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12253        final long curUptime = SystemClock.uptimeMillis();
12254        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12255
12256        for (int i=list.size()-1; i>=0; i--) {
12257            ProcessRecord r = list.get(i).first;
12258            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12259            char schedGroup;
12260            switch (r.setSchedGroup) {
12261                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12262                    schedGroup = 'B';
12263                    break;
12264                case Process.THREAD_GROUP_DEFAULT:
12265                    schedGroup = 'F';
12266                    break;
12267                default:
12268                    schedGroup = '?';
12269                    break;
12270            }
12271            char foreground;
12272            if (r.foregroundActivities) {
12273                foreground = 'A';
12274            } else if (r.foregroundServices) {
12275                foreground = 'S';
12276            } else {
12277                foreground = ' ';
12278            }
12279            String procState = ProcessList.makeProcStateString(r.curProcState);
12280            pw.print(prefix);
12281            pw.print(r.persistent ? persistentLabel : normalLabel);
12282            pw.print(" #");
12283            int num = (origList.size()-1)-list.get(i).second;
12284            if (num < 10) pw.print(' ');
12285            pw.print(num);
12286            pw.print(": ");
12287            pw.print(oomAdj);
12288            pw.print(' ');
12289            pw.print(schedGroup);
12290            pw.print('/');
12291            pw.print(foreground);
12292            pw.print('/');
12293            pw.print(procState);
12294            pw.print(" trm:");
12295            if (r.trimMemoryLevel < 10) pw.print(' ');
12296            pw.print(r.trimMemoryLevel);
12297            pw.print(' ');
12298            pw.print(r.toShortString());
12299            pw.print(" (");
12300            pw.print(r.adjType);
12301            pw.println(')');
12302            if (r.adjSource != null || r.adjTarget != null) {
12303                pw.print(prefix);
12304                pw.print("    ");
12305                if (r.adjTarget instanceof ComponentName) {
12306                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12307                } else if (r.adjTarget != null) {
12308                    pw.print(r.adjTarget.toString());
12309                } else {
12310                    pw.print("{null}");
12311                }
12312                pw.print("<=");
12313                if (r.adjSource instanceof ProcessRecord) {
12314                    pw.print("Proc{");
12315                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12316                    pw.println("}");
12317                } else if (r.adjSource != null) {
12318                    pw.println(r.adjSource.toString());
12319                } else {
12320                    pw.println("{null}");
12321                }
12322            }
12323            if (inclDetails) {
12324                pw.print(prefix);
12325                pw.print("    ");
12326                pw.print("oom: max="); pw.print(r.maxAdj);
12327                pw.print(" curRaw="); pw.print(r.curRawAdj);
12328                pw.print(" setRaw="); pw.print(r.setRawAdj);
12329                pw.print(" cur="); pw.print(r.curAdj);
12330                pw.print(" set="); pw.println(r.setAdj);
12331                pw.print(prefix);
12332                pw.print("    ");
12333                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12334                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12335                pw.print(" lastPss="); pw.print(r.lastPss);
12336                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12337                pw.print(prefix);
12338                pw.print("    ");
12339                pw.print("keeping="); pw.print(r.keeping);
12340                pw.print(" cached="); pw.print(r.cached);
12341                pw.print(" empty="); pw.print(r.empty);
12342                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12343
12344                if (!r.keeping) {
12345                    if (r.lastWakeTime != 0) {
12346                        long wtime;
12347                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12348                        synchronized (stats) {
12349                            wtime = stats.getProcessWakeTime(r.info.uid,
12350                                    r.pid, curRealtime);
12351                        }
12352                        long timeUsed = wtime - r.lastWakeTime;
12353                        pw.print(prefix);
12354                        pw.print("    ");
12355                        pw.print("keep awake over ");
12356                        TimeUtils.formatDuration(realtimeSince, pw);
12357                        pw.print(" used ");
12358                        TimeUtils.formatDuration(timeUsed, pw);
12359                        pw.print(" (");
12360                        pw.print((timeUsed*100)/realtimeSince);
12361                        pw.println("%)");
12362                    }
12363                    if (r.lastCpuTime != 0) {
12364                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12365                        pw.print(prefix);
12366                        pw.print("    ");
12367                        pw.print("run cpu over ");
12368                        TimeUtils.formatDuration(uptimeSince, pw);
12369                        pw.print(" used ");
12370                        TimeUtils.formatDuration(timeUsed, pw);
12371                        pw.print(" (");
12372                        pw.print((timeUsed*100)/uptimeSince);
12373                        pw.println("%)");
12374                    }
12375                }
12376            }
12377        }
12378        return true;
12379    }
12380
12381    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12382        ArrayList<ProcessRecord> procs;
12383        synchronized (this) {
12384            if (args != null && args.length > start
12385                    && args[start].charAt(0) != '-') {
12386                procs = new ArrayList<ProcessRecord>();
12387                int pid = -1;
12388                try {
12389                    pid = Integer.parseInt(args[start]);
12390                } catch (NumberFormatException e) {
12391                }
12392                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12393                    ProcessRecord proc = mLruProcesses.get(i);
12394                    if (proc.pid == pid) {
12395                        procs.add(proc);
12396                    } else if (proc.processName.equals(args[start])) {
12397                        procs.add(proc);
12398                    }
12399                }
12400                if (procs.size() <= 0) {
12401                    return null;
12402                }
12403            } else {
12404                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12405            }
12406        }
12407        return procs;
12408    }
12409
12410    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12411            PrintWriter pw, String[] args) {
12412        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12413        if (procs == null) {
12414            pw.println("No process found for: " + args[0]);
12415            return;
12416        }
12417
12418        long uptime = SystemClock.uptimeMillis();
12419        long realtime = SystemClock.elapsedRealtime();
12420        pw.println("Applications Graphics Acceleration Info:");
12421        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12422
12423        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12424            ProcessRecord r = procs.get(i);
12425            if (r.thread != null) {
12426                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12427                pw.flush();
12428                try {
12429                    TransferPipe tp = new TransferPipe();
12430                    try {
12431                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12432                        tp.go(fd);
12433                    } finally {
12434                        tp.kill();
12435                    }
12436                } catch (IOException e) {
12437                    pw.println("Failure while dumping the app: " + r);
12438                    pw.flush();
12439                } catch (RemoteException e) {
12440                    pw.println("Got a RemoteException while dumping the app " + r);
12441                    pw.flush();
12442                }
12443            }
12444        }
12445    }
12446
12447    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12448        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12449        if (procs == null) {
12450            pw.println("No process found for: " + args[0]);
12451            return;
12452        }
12453
12454        pw.println("Applications Database Info:");
12455
12456        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12457            ProcessRecord r = procs.get(i);
12458            if (r.thread != null) {
12459                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12460                pw.flush();
12461                try {
12462                    TransferPipe tp = new TransferPipe();
12463                    try {
12464                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12465                        tp.go(fd);
12466                    } finally {
12467                        tp.kill();
12468                    }
12469                } catch (IOException e) {
12470                    pw.println("Failure while dumping the app: " + r);
12471                    pw.flush();
12472                } catch (RemoteException e) {
12473                    pw.println("Got a RemoteException while dumping the app " + r);
12474                    pw.flush();
12475                }
12476            }
12477        }
12478    }
12479
12480    final static class MemItem {
12481        final boolean isProc;
12482        final String label;
12483        final String shortLabel;
12484        final long pss;
12485        final int id;
12486        final boolean hasActivities;
12487        ArrayList<MemItem> subitems;
12488
12489        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12490                boolean _hasActivities) {
12491            isProc = true;
12492            label = _label;
12493            shortLabel = _shortLabel;
12494            pss = _pss;
12495            id = _id;
12496            hasActivities = _hasActivities;
12497        }
12498
12499        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12500            isProc = false;
12501            label = _label;
12502            shortLabel = _shortLabel;
12503            pss = _pss;
12504            id = _id;
12505            hasActivities = false;
12506        }
12507    }
12508
12509    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12510            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12511        if (sort && !isCompact) {
12512            Collections.sort(items, new Comparator<MemItem>() {
12513                @Override
12514                public int compare(MemItem lhs, MemItem rhs) {
12515                    if (lhs.pss < rhs.pss) {
12516                        return 1;
12517                    } else if (lhs.pss > rhs.pss) {
12518                        return -1;
12519                    }
12520                    return 0;
12521                }
12522            });
12523        }
12524
12525        for (int i=0; i<items.size(); i++) {
12526            MemItem mi = items.get(i);
12527            if (!isCompact) {
12528                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12529            } else if (mi.isProc) {
12530                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12531                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12532                pw.println(mi.hasActivities ? ",a" : ",e");
12533            } else {
12534                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12535                pw.println(mi.pss);
12536            }
12537            if (mi.subitems != null) {
12538                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12539                        true, isCompact);
12540            }
12541        }
12542    }
12543
12544    // These are in KB.
12545    static final long[] DUMP_MEM_BUCKETS = new long[] {
12546        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12547        120*1024, 160*1024, 200*1024,
12548        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12549        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12550    };
12551
12552    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12553            boolean stackLike) {
12554        int start = label.lastIndexOf('.');
12555        if (start >= 0) start++;
12556        else start = 0;
12557        int end = label.length();
12558        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12559            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12560                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12561                out.append(bucket);
12562                out.append(stackLike ? "MB." : "MB ");
12563                out.append(label, start, end);
12564                return;
12565            }
12566        }
12567        out.append(memKB/1024);
12568        out.append(stackLike ? "MB." : "MB ");
12569        out.append(label, start, end);
12570    }
12571
12572    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12573            ProcessList.NATIVE_ADJ,
12574            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12575            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12576            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12577            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12578            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12579    };
12580    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12581            "Native",
12582            "System", "Persistent", "Foreground",
12583            "Visible", "Perceptible",
12584            "Heavy Weight", "Backup",
12585            "A Services", "Home",
12586            "Previous", "B Services", "Cached"
12587    };
12588    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12589            "native",
12590            "sys", "pers", "fore",
12591            "vis", "percept",
12592            "heavy", "backup",
12593            "servicea", "home",
12594            "prev", "serviceb", "cached"
12595    };
12596
12597    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12598            long realtime, boolean isCheckinRequest, boolean isCompact) {
12599        if (isCheckinRequest || isCompact) {
12600            // short checkin version
12601            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12602        } else {
12603            pw.println("Applications Memory Usage (kB):");
12604            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12605        }
12606    }
12607
12608    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12609            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12610        boolean dumpDetails = false;
12611        boolean dumpFullDetails = false;
12612        boolean dumpDalvik = false;
12613        boolean oomOnly = false;
12614        boolean isCompact = false;
12615        boolean localOnly = false;
12616
12617        int opti = 0;
12618        while (opti < args.length) {
12619            String opt = args[opti];
12620            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12621                break;
12622            }
12623            opti++;
12624            if ("-a".equals(opt)) {
12625                dumpDetails = true;
12626                dumpFullDetails = true;
12627                dumpDalvik = true;
12628            } else if ("-d".equals(opt)) {
12629                dumpDalvik = true;
12630            } else if ("-c".equals(opt)) {
12631                isCompact = true;
12632            } else if ("--oom".equals(opt)) {
12633                oomOnly = true;
12634            } else if ("--local".equals(opt)) {
12635                localOnly = true;
12636            } else if ("-h".equals(opt)) {
12637                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12638                pw.println("  -a: include all available information for each process.");
12639                pw.println("  -d: include dalvik details when dumping process details.");
12640                pw.println("  -c: dump in a compact machine-parseable representation.");
12641                pw.println("  --oom: only show processes organized by oom adj.");
12642                pw.println("  --local: only collect details locally, don't call process.");
12643                pw.println("If [process] is specified it can be the name or ");
12644                pw.println("pid of a specific process to dump.");
12645                return;
12646            } else {
12647                pw.println("Unknown argument: " + opt + "; use -h for help");
12648            }
12649        }
12650
12651        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12652        long uptime = SystemClock.uptimeMillis();
12653        long realtime = SystemClock.elapsedRealtime();
12654        final long[] tmpLong = new long[1];
12655
12656        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12657        if (procs == null) {
12658            // No Java processes.  Maybe they want to print a native process.
12659            if (args != null && args.length > opti
12660                    && args[opti].charAt(0) != '-') {
12661                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12662                        = new ArrayList<ProcessCpuTracker.Stats>();
12663                updateCpuStatsNow();
12664                int findPid = -1;
12665                try {
12666                    findPid = Integer.parseInt(args[opti]);
12667                } catch (NumberFormatException e) {
12668                }
12669                synchronized (mProcessCpuThread) {
12670                    final int N = mProcessCpuTracker.countStats();
12671                    for (int i=0; i<N; i++) {
12672                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12673                        if (st.pid == findPid || (st.baseName != null
12674                                && st.baseName.equals(args[opti]))) {
12675                            nativeProcs.add(st);
12676                        }
12677                    }
12678                }
12679                if (nativeProcs.size() > 0) {
12680                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12681                            isCompact);
12682                    Debug.MemoryInfo mi = null;
12683                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12684                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12685                        final int pid = r.pid;
12686                        if (!isCheckinRequest && dumpDetails) {
12687                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12688                        }
12689                        if (mi == null) {
12690                            mi = new Debug.MemoryInfo();
12691                        }
12692                        if (dumpDetails || (!brief && !oomOnly)) {
12693                            Debug.getMemoryInfo(pid, mi);
12694                        } else {
12695                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12696                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12697                        }
12698                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12699                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12700                        if (isCheckinRequest) {
12701                            pw.println();
12702                        }
12703                    }
12704                    return;
12705                }
12706            }
12707            pw.println("No process found for: " + args[opti]);
12708            return;
12709        }
12710
12711        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12712            dumpDetails = true;
12713        }
12714
12715        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12716
12717        String[] innerArgs = new String[args.length-opti];
12718        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12719
12720        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12721        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12722        long nativePss=0, dalvikPss=0, otherPss=0;
12723        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12724
12725        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12726        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12727                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12728
12729        long totalPss = 0;
12730        long cachedPss = 0;
12731
12732        Debug.MemoryInfo mi = null;
12733        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12734            final ProcessRecord r = procs.get(i);
12735            final IApplicationThread thread;
12736            final int pid;
12737            final int oomAdj;
12738            final boolean hasActivities;
12739            synchronized (this) {
12740                thread = r.thread;
12741                pid = r.pid;
12742                oomAdj = r.getSetAdjWithServices();
12743                hasActivities = r.activities.size() > 0;
12744            }
12745            if (thread != null) {
12746                if (!isCheckinRequest && dumpDetails) {
12747                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12748                }
12749                if (mi == null) {
12750                    mi = new Debug.MemoryInfo();
12751                }
12752                if (dumpDetails || (!brief && !oomOnly)) {
12753                    Debug.getMemoryInfo(pid, mi);
12754                } else {
12755                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12756                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12757                }
12758                if (dumpDetails) {
12759                    if (localOnly) {
12760                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12761                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12762                        if (isCheckinRequest) {
12763                            pw.println();
12764                        }
12765                    } else {
12766                        try {
12767                            pw.flush();
12768                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12769                                    dumpDalvik, innerArgs);
12770                        } catch (RemoteException e) {
12771                            if (!isCheckinRequest) {
12772                                pw.println("Got RemoteException!");
12773                                pw.flush();
12774                            }
12775                        }
12776                    }
12777                }
12778
12779                final long myTotalPss = mi.getTotalPss();
12780                final long myTotalUss = mi.getTotalUss();
12781
12782                synchronized (this) {
12783                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12784                        // Record this for posterity if the process has been stable.
12785                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12786                    }
12787                }
12788
12789                if (!isCheckinRequest && mi != null) {
12790                    totalPss += myTotalPss;
12791                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12792                            (hasActivities ? " / activities)" : ")"),
12793                            r.processName, myTotalPss, pid, hasActivities);
12794                    procMems.add(pssItem);
12795                    procMemsMap.put(pid, pssItem);
12796
12797                    nativePss += mi.nativePss;
12798                    dalvikPss += mi.dalvikPss;
12799                    otherPss += mi.otherPss;
12800                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12801                        long mem = mi.getOtherPss(j);
12802                        miscPss[j] += mem;
12803                        otherPss -= mem;
12804                    }
12805
12806                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12807                        cachedPss += myTotalPss;
12808                    }
12809
12810                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12811                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12812                                || oomIndex == (oomPss.length-1)) {
12813                            oomPss[oomIndex] += myTotalPss;
12814                            if (oomProcs[oomIndex] == null) {
12815                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12816                            }
12817                            oomProcs[oomIndex].add(pssItem);
12818                            break;
12819                        }
12820                    }
12821                }
12822            }
12823        }
12824
12825        long nativeProcTotalPss = 0;
12826
12827        if (!isCheckinRequest && procs.size() > 1) {
12828            // If we are showing aggregations, also look for native processes to
12829            // include so that our aggregations are more accurate.
12830            updateCpuStatsNow();
12831            synchronized (mProcessCpuThread) {
12832                final int N = mProcessCpuTracker.countStats();
12833                for (int i=0; i<N; i++) {
12834                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12835                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12836                        if (mi == null) {
12837                            mi = new Debug.MemoryInfo();
12838                        }
12839                        if (!brief && !oomOnly) {
12840                            Debug.getMemoryInfo(st.pid, mi);
12841                        } else {
12842                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12843                            mi.nativePrivateDirty = (int)tmpLong[0];
12844                        }
12845
12846                        final long myTotalPss = mi.getTotalPss();
12847                        totalPss += myTotalPss;
12848                        nativeProcTotalPss += myTotalPss;
12849
12850                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12851                                st.name, myTotalPss, st.pid, false);
12852                        procMems.add(pssItem);
12853
12854                        nativePss += mi.nativePss;
12855                        dalvikPss += mi.dalvikPss;
12856                        otherPss += mi.otherPss;
12857                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12858                            long mem = mi.getOtherPss(j);
12859                            miscPss[j] += mem;
12860                            otherPss -= mem;
12861                        }
12862                        oomPss[0] += myTotalPss;
12863                        if (oomProcs[0] == null) {
12864                            oomProcs[0] = new ArrayList<MemItem>();
12865                        }
12866                        oomProcs[0].add(pssItem);
12867                    }
12868                }
12869            }
12870
12871            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12872
12873            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12874            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12875            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12876            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12877                String label = Debug.MemoryInfo.getOtherLabel(j);
12878                catMems.add(new MemItem(label, label, miscPss[j], j));
12879            }
12880
12881            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12882            for (int j=0; j<oomPss.length; j++) {
12883                if (oomPss[j] != 0) {
12884                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12885                            : DUMP_MEM_OOM_LABEL[j];
12886                    MemItem item = new MemItem(label, label, oomPss[j],
12887                            DUMP_MEM_OOM_ADJ[j]);
12888                    item.subitems = oomProcs[j];
12889                    oomMems.add(item);
12890                }
12891            }
12892
12893            if (!brief && !oomOnly && !isCompact) {
12894                pw.println();
12895                pw.println("Total PSS by process:");
12896                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12897                pw.println();
12898            }
12899            if (!isCompact) {
12900                pw.println("Total PSS by OOM adjustment:");
12901            }
12902            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12903            if (!brief && !oomOnly) {
12904                PrintWriter out = categoryPw != null ? categoryPw : pw;
12905                if (!isCompact) {
12906                    out.println();
12907                    out.println("Total PSS by category:");
12908                }
12909                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12910            }
12911            if (!isCompact) {
12912                pw.println();
12913            }
12914            MemInfoReader memInfo = new MemInfoReader();
12915            memInfo.readMemInfo();
12916            if (nativeProcTotalPss > 0) {
12917                synchronized (this) {
12918                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12919                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12920                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12921                            nativeProcTotalPss);
12922                }
12923            }
12924            if (!brief) {
12925                if (!isCompact) {
12926                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12927                    pw.print(" kB (status ");
12928                    switch (mLastMemoryLevel) {
12929                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12930                            pw.println("normal)");
12931                            break;
12932                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12933                            pw.println("moderate)");
12934                            break;
12935                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12936                            pw.println("low)");
12937                            break;
12938                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12939                            pw.println("critical)");
12940                            break;
12941                        default:
12942                            pw.print(mLastMemoryLevel);
12943                            pw.println(")");
12944                            break;
12945                    }
12946                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12947                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12948                            pw.print(cachedPss); pw.print(" cached pss + ");
12949                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12950                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12951                } else {
12952                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12953                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12954                            + memInfo.getFreeSizeKb()); pw.print(",");
12955                    pw.println(totalPss - cachedPss);
12956                }
12957            }
12958            if (!isCompact) {
12959                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12960                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12961                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12962                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12963                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12964                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12965                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12966                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12967                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12968                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12969                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12970            }
12971            if (!brief) {
12972                if (memInfo.getZramTotalSizeKb() != 0) {
12973                    if (!isCompact) {
12974                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12975                                pw.print(" kB physical used for ");
12976                                pw.print(memInfo.getSwapTotalSizeKb()
12977                                        - memInfo.getSwapFreeSizeKb());
12978                                pw.print(" kB in swap (");
12979                                pw.print(memInfo.getSwapTotalSizeKb());
12980                                pw.println(" kB total swap)");
12981                    } else {
12982                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12983                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12984                                pw.println(memInfo.getSwapFreeSizeKb());
12985                    }
12986                }
12987                final int[] SINGLE_LONG_FORMAT = new int[] {
12988                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12989                };
12990                long[] longOut = new long[1];
12991                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12992                        SINGLE_LONG_FORMAT, null, longOut, null);
12993                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12994                longOut[0] = 0;
12995                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12996                        SINGLE_LONG_FORMAT, null, longOut, null);
12997                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12998                longOut[0] = 0;
12999                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13000                        SINGLE_LONG_FORMAT, null, longOut, null);
13001                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13002                longOut[0] = 0;
13003                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13004                        SINGLE_LONG_FORMAT, null, longOut, null);
13005                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13006                if (!isCompact) {
13007                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13008                        pw.print("      KSM: "); pw.print(sharing);
13009                                pw.print(" kB saved from shared ");
13010                                pw.print(shared); pw.println(" kB");
13011                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13012                                pw.print(voltile); pw.println(" kB volatile");
13013                    }
13014                    pw.print("   Tuning: ");
13015                    pw.print(ActivityManager.staticGetMemoryClass());
13016                    pw.print(" (large ");
13017                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13018                    pw.print("), oom ");
13019                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13020                    pw.print(" kB");
13021                    pw.print(", restore limit ");
13022                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13023                    pw.print(" kB");
13024                    if (ActivityManager.isLowRamDeviceStatic()) {
13025                        pw.print(" (low-ram)");
13026                    }
13027                    if (ActivityManager.isHighEndGfx()) {
13028                        pw.print(" (high-end-gfx)");
13029                    }
13030                    pw.println();
13031                } else {
13032                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13033                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13034                    pw.println(voltile);
13035                    pw.print("tuning,");
13036                    pw.print(ActivityManager.staticGetMemoryClass());
13037                    pw.print(',');
13038                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13039                    pw.print(',');
13040                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13041                    if (ActivityManager.isLowRamDeviceStatic()) {
13042                        pw.print(",low-ram");
13043                    }
13044                    if (ActivityManager.isHighEndGfx()) {
13045                        pw.print(",high-end-gfx");
13046                    }
13047                    pw.println();
13048                }
13049            }
13050        }
13051    }
13052
13053    /**
13054     * Searches array of arguments for the specified string
13055     * @param args array of argument strings
13056     * @param value value to search for
13057     * @return true if the value is contained in the array
13058     */
13059    private static boolean scanArgs(String[] args, String value) {
13060        if (args != null) {
13061            for (String arg : args) {
13062                if (value.equals(arg)) {
13063                    return true;
13064                }
13065            }
13066        }
13067        return false;
13068    }
13069
13070    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13071            ContentProviderRecord cpr, boolean always) {
13072        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13073
13074        if (!inLaunching || always) {
13075            synchronized (cpr) {
13076                cpr.launchingApp = null;
13077                cpr.notifyAll();
13078            }
13079            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13080            String names[] = cpr.info.authority.split(";");
13081            for (int j = 0; j < names.length; j++) {
13082                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13083            }
13084        }
13085
13086        for (int i=0; i<cpr.connections.size(); i++) {
13087            ContentProviderConnection conn = cpr.connections.get(i);
13088            if (conn.waiting) {
13089                // If this connection is waiting for the provider, then we don't
13090                // need to mess with its process unless we are always removing
13091                // or for some reason the provider is not currently launching.
13092                if (inLaunching && !always) {
13093                    continue;
13094                }
13095            }
13096            ProcessRecord capp = conn.client;
13097            conn.dead = true;
13098            if (conn.stableCount > 0) {
13099                if (!capp.persistent && capp.thread != null
13100                        && capp.pid != 0
13101                        && capp.pid != MY_PID) {
13102                    killUnneededProcessLocked(capp, "depends on provider "
13103                            + cpr.name.flattenToShortString()
13104                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13105                }
13106            } else if (capp.thread != null && conn.provider.provider != null) {
13107                try {
13108                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13109                } catch (RemoteException e) {
13110                }
13111                // In the protocol here, we don't expect the client to correctly
13112                // clean up this connection, we'll just remove it.
13113                cpr.connections.remove(i);
13114                conn.client.conProviders.remove(conn);
13115            }
13116        }
13117
13118        if (inLaunching && always) {
13119            mLaunchingProviders.remove(cpr);
13120        }
13121        return inLaunching;
13122    }
13123
13124    /**
13125     * Main code for cleaning up a process when it has gone away.  This is
13126     * called both as a result of the process dying, or directly when stopping
13127     * a process when running in single process mode.
13128     */
13129    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13130            boolean restarting, boolean allowRestart, int index) {
13131        if (index >= 0) {
13132            removeLruProcessLocked(app);
13133            ProcessList.remove(app.pid);
13134        }
13135
13136        mProcessesToGc.remove(app);
13137        mPendingPssProcesses.remove(app);
13138
13139        // Dismiss any open dialogs.
13140        if (app.crashDialog != null && !app.forceCrashReport) {
13141            app.crashDialog.dismiss();
13142            app.crashDialog = null;
13143        }
13144        if (app.anrDialog != null) {
13145            app.anrDialog.dismiss();
13146            app.anrDialog = null;
13147        }
13148        if (app.waitDialog != null) {
13149            app.waitDialog.dismiss();
13150            app.waitDialog = null;
13151        }
13152
13153        app.crashing = false;
13154        app.notResponding = false;
13155
13156        app.resetPackageList(mProcessStats);
13157        app.unlinkDeathRecipient();
13158        app.makeInactive(mProcessStats);
13159        app.waitingToKill = null;
13160        app.forcingToForeground = null;
13161        updateProcessForegroundLocked(app, false, false);
13162        app.foregroundActivities = false;
13163        app.hasShownUi = false;
13164        app.treatLikeActivity = false;
13165        app.hasAboveClient = false;
13166        app.hasClientActivities = false;
13167
13168        mServices.killServicesLocked(app, allowRestart);
13169
13170        boolean restart = false;
13171
13172        // Remove published content providers.
13173        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13174            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13175            final boolean always = app.bad || !allowRestart;
13176            if (removeDyingProviderLocked(app, cpr, always) || always) {
13177                // We left the provider in the launching list, need to
13178                // restart it.
13179                restart = true;
13180            }
13181
13182            cpr.provider = null;
13183            cpr.proc = null;
13184        }
13185        app.pubProviders.clear();
13186
13187        // Take care of any launching providers waiting for this process.
13188        if (checkAppInLaunchingProvidersLocked(app, false)) {
13189            restart = true;
13190        }
13191
13192        // Unregister from connected content providers.
13193        if (!app.conProviders.isEmpty()) {
13194            for (int i=0; i<app.conProviders.size(); i++) {
13195                ContentProviderConnection conn = app.conProviders.get(i);
13196                conn.provider.connections.remove(conn);
13197            }
13198            app.conProviders.clear();
13199        }
13200
13201        // At this point there may be remaining entries in mLaunchingProviders
13202        // where we were the only one waiting, so they are no longer of use.
13203        // Look for these and clean up if found.
13204        // XXX Commented out for now.  Trying to figure out a way to reproduce
13205        // the actual situation to identify what is actually going on.
13206        if (false) {
13207            for (int i=0; i<mLaunchingProviders.size(); i++) {
13208                ContentProviderRecord cpr = (ContentProviderRecord)
13209                        mLaunchingProviders.get(i);
13210                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13211                    synchronized (cpr) {
13212                        cpr.launchingApp = null;
13213                        cpr.notifyAll();
13214                    }
13215                }
13216            }
13217        }
13218
13219        skipCurrentReceiverLocked(app);
13220
13221        // Unregister any receivers.
13222        for (int i=app.receivers.size()-1; i>=0; i--) {
13223            removeReceiverLocked(app.receivers.valueAt(i));
13224        }
13225        app.receivers.clear();
13226
13227        // If the app is undergoing backup, tell the backup manager about it
13228        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13229            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13230                    + mBackupTarget.appInfo + " died during backup");
13231            try {
13232                IBackupManager bm = IBackupManager.Stub.asInterface(
13233                        ServiceManager.getService(Context.BACKUP_SERVICE));
13234                bm.agentDisconnected(app.info.packageName);
13235            } catch (RemoteException e) {
13236                // can't happen; backup manager is local
13237            }
13238        }
13239
13240        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13241            ProcessChangeItem item = mPendingProcessChanges.get(i);
13242            if (item.pid == app.pid) {
13243                mPendingProcessChanges.remove(i);
13244                mAvailProcessChanges.add(item);
13245            }
13246        }
13247        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13248
13249        // If the caller is restarting this app, then leave it in its
13250        // current lists and let the caller take care of it.
13251        if (restarting) {
13252            return;
13253        }
13254
13255        if (!app.persistent || app.isolated) {
13256            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13257                    "Removing non-persistent process during cleanup: " + app);
13258            mProcessNames.remove(app.processName, app.uid);
13259            mIsolatedProcesses.remove(app.uid);
13260            if (mHeavyWeightProcess == app) {
13261                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13262                        mHeavyWeightProcess.userId, 0));
13263                mHeavyWeightProcess = null;
13264            }
13265        } else if (!app.removed) {
13266            // This app is persistent, so we need to keep its record around.
13267            // If it is not already on the pending app list, add it there
13268            // and start a new process for it.
13269            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13270                mPersistentStartingProcesses.add(app);
13271                restart = true;
13272            }
13273        }
13274        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13275                "Clean-up removing on hold: " + app);
13276        mProcessesOnHold.remove(app);
13277
13278        if (app == mHomeProcess) {
13279            mHomeProcess = null;
13280        }
13281        if (app == mPreviousProcess) {
13282            mPreviousProcess = null;
13283        }
13284
13285        if (restart && !app.isolated) {
13286            // We have components that still need to be running in the
13287            // process, so re-launch it.
13288            mProcessNames.put(app.processName, app.uid, app);
13289            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13290        } else if (app.pid > 0 && app.pid != MY_PID) {
13291            // Goodbye!
13292            boolean removed;
13293            synchronized (mPidsSelfLocked) {
13294                mPidsSelfLocked.remove(app.pid);
13295                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13296            }
13297            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13298            if (app.isolated) {
13299                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13300            }
13301            app.setPid(0);
13302        }
13303    }
13304
13305    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13306        // Look through the content providers we are waiting to have launched,
13307        // and if any run in this process then either schedule a restart of
13308        // the process or kill the client waiting for it if this process has
13309        // gone bad.
13310        int NL = mLaunchingProviders.size();
13311        boolean restart = false;
13312        for (int i=0; i<NL; i++) {
13313            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13314            if (cpr.launchingApp == app) {
13315                if (!alwaysBad && !app.bad) {
13316                    restart = true;
13317                } else {
13318                    removeDyingProviderLocked(app, cpr, true);
13319                    // cpr should have been removed from mLaunchingProviders
13320                    NL = mLaunchingProviders.size();
13321                    i--;
13322                }
13323            }
13324        }
13325        return restart;
13326    }
13327
13328    // =========================================================
13329    // SERVICES
13330    // =========================================================
13331
13332    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13333            int flags) {
13334        enforceNotIsolatedCaller("getServices");
13335        synchronized (this) {
13336            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13337        }
13338    }
13339
13340    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13341        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13342        synchronized (this) {
13343            return mServices.getRunningServiceControlPanelLocked(name);
13344        }
13345    }
13346
13347    public ComponentName startService(IApplicationThread caller, Intent service,
13348            String resolvedType, int userId) {
13349        enforceNotIsolatedCaller("startService");
13350        // Refuse possible leaked file descriptors
13351        if (service != null && service.hasFileDescriptors() == true) {
13352            throw new IllegalArgumentException("File descriptors passed in Intent");
13353        }
13354
13355        if (DEBUG_SERVICE)
13356            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13357        synchronized(this) {
13358            final int callingPid = Binder.getCallingPid();
13359            final int callingUid = Binder.getCallingUid();
13360            final long origId = Binder.clearCallingIdentity();
13361            ComponentName res = mServices.startServiceLocked(caller, service,
13362                    resolvedType, callingPid, callingUid, userId);
13363            Binder.restoreCallingIdentity(origId);
13364            return res;
13365        }
13366    }
13367
13368    ComponentName startServiceInPackage(int uid,
13369            Intent service, String resolvedType, int userId) {
13370        synchronized(this) {
13371            if (DEBUG_SERVICE)
13372                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13373            final long origId = Binder.clearCallingIdentity();
13374            ComponentName res = mServices.startServiceLocked(null, service,
13375                    resolvedType, -1, uid, userId);
13376            Binder.restoreCallingIdentity(origId);
13377            return res;
13378        }
13379    }
13380
13381    public int stopService(IApplicationThread caller, Intent service,
13382            String resolvedType, int userId) {
13383        enforceNotIsolatedCaller("stopService");
13384        // Refuse possible leaked file descriptors
13385        if (service != null && service.hasFileDescriptors() == true) {
13386            throw new IllegalArgumentException("File descriptors passed in Intent");
13387        }
13388
13389        synchronized(this) {
13390            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13391        }
13392    }
13393
13394    public IBinder peekService(Intent service, String resolvedType) {
13395        enforceNotIsolatedCaller("peekService");
13396        // Refuse possible leaked file descriptors
13397        if (service != null && service.hasFileDescriptors() == true) {
13398            throw new IllegalArgumentException("File descriptors passed in Intent");
13399        }
13400        synchronized(this) {
13401            return mServices.peekServiceLocked(service, resolvedType);
13402        }
13403    }
13404
13405    public boolean stopServiceToken(ComponentName className, IBinder token,
13406            int startId) {
13407        synchronized(this) {
13408            return mServices.stopServiceTokenLocked(className, token, startId);
13409        }
13410    }
13411
13412    public void setServiceForeground(ComponentName className, IBinder token,
13413            int id, Notification notification, boolean removeNotification) {
13414        synchronized(this) {
13415            mServices.setServiceForegroundLocked(className, token, id, notification,
13416                    removeNotification);
13417        }
13418    }
13419
13420    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13421            boolean requireFull, String name, String callerPackage) {
13422        final int callingUserId = UserHandle.getUserId(callingUid);
13423        if (callingUserId != userId) {
13424            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13425                if ((requireFull || checkComponentPermission(
13426                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13427                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13428                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13429                                callingPid, callingUid, -1, true)
13430                                != PackageManager.PERMISSION_GRANTED) {
13431                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13432                        // In this case, they would like to just execute as their
13433                        // owner user instead of failing.
13434                        userId = callingUserId;
13435                    } else {
13436                        StringBuilder builder = new StringBuilder(128);
13437                        builder.append("Permission Denial: ");
13438                        builder.append(name);
13439                        if (callerPackage != null) {
13440                            builder.append(" from ");
13441                            builder.append(callerPackage);
13442                        }
13443                        builder.append(" asks to run as user ");
13444                        builder.append(userId);
13445                        builder.append(" but is calling from user ");
13446                        builder.append(UserHandle.getUserId(callingUid));
13447                        builder.append("; this requires ");
13448                        builder.append(INTERACT_ACROSS_USERS_FULL);
13449                        if (!requireFull) {
13450                            builder.append(" or ");
13451                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13452                        }
13453                        String msg = builder.toString();
13454                        Slog.w(TAG, msg);
13455                        throw new SecurityException(msg);
13456                    }
13457                }
13458            }
13459            if (userId == UserHandle.USER_CURRENT
13460                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13461                // Note that we may be accessing this outside of a lock...
13462                // shouldn't be a big deal, if this is being called outside
13463                // of a locked context there is intrinsically a race with
13464                // the value the caller will receive and someone else changing it.
13465                userId = mCurrentUserId;
13466            }
13467            if (!allowAll && userId < 0) {
13468                throw new IllegalArgumentException(
13469                        "Call does not support special user #" + userId);
13470            }
13471        }
13472        return userId;
13473    }
13474
13475    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13476            String className, int flags) {
13477        boolean result = false;
13478        // For apps that don't have pre-defined UIDs, check for permission
13479        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13480            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13481                if (ActivityManager.checkUidPermission(
13482                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13483                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13484                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13485                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13486                            + " requests FLAG_SINGLE_USER, but app does not hold "
13487                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13488                    Slog.w(TAG, msg);
13489                    throw new SecurityException(msg);
13490                }
13491                // Permission passed
13492                result = true;
13493            }
13494        } else if ("system".equals(componentProcessName)) {
13495            result = true;
13496        } else {
13497            // App with pre-defined UID, check if it's a persistent app
13498            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13499        }
13500        if (DEBUG_MU) {
13501            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13502                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13503        }
13504        return result;
13505    }
13506
13507    /**
13508     * Checks to see if the caller is in the same app as the singleton
13509     * component, or the component is in a special app. It allows special apps
13510     * to export singleton components but prevents exporting singleton
13511     * components for regular apps.
13512     */
13513    boolean isValidSingletonCall(int callingUid, int componentUid) {
13514        int componentAppId = UserHandle.getAppId(componentUid);
13515        return UserHandle.isSameApp(callingUid, componentUid)
13516                || componentAppId == Process.SYSTEM_UID
13517                || componentAppId == Process.PHONE_UID
13518                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13519                        == PackageManager.PERMISSION_GRANTED;
13520    }
13521
13522    public int bindService(IApplicationThread caller, IBinder token,
13523            Intent service, String resolvedType,
13524            IServiceConnection connection, int flags, int userId) {
13525        enforceNotIsolatedCaller("bindService");
13526        // Refuse possible leaked file descriptors
13527        if (service != null && service.hasFileDescriptors() == true) {
13528            throw new IllegalArgumentException("File descriptors passed in Intent");
13529        }
13530
13531        synchronized(this) {
13532            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13533                    connection, flags, userId);
13534        }
13535    }
13536
13537    public boolean unbindService(IServiceConnection connection) {
13538        synchronized (this) {
13539            return mServices.unbindServiceLocked(connection);
13540        }
13541    }
13542
13543    public void publishService(IBinder token, Intent intent, IBinder service) {
13544        // Refuse possible leaked file descriptors
13545        if (intent != null && intent.hasFileDescriptors() == true) {
13546            throw new IllegalArgumentException("File descriptors passed in Intent");
13547        }
13548
13549        synchronized(this) {
13550            if (!(token instanceof ServiceRecord)) {
13551                throw new IllegalArgumentException("Invalid service token");
13552            }
13553            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13554        }
13555    }
13556
13557    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13558        // Refuse possible leaked file descriptors
13559        if (intent != null && intent.hasFileDescriptors() == true) {
13560            throw new IllegalArgumentException("File descriptors passed in Intent");
13561        }
13562
13563        synchronized(this) {
13564            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13565        }
13566    }
13567
13568    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13569        synchronized(this) {
13570            if (!(token instanceof ServiceRecord)) {
13571                throw new IllegalArgumentException("Invalid service token");
13572            }
13573            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13574        }
13575    }
13576
13577    // =========================================================
13578    // BACKUP AND RESTORE
13579    // =========================================================
13580
13581    // Cause the target app to be launched if necessary and its backup agent
13582    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13583    // activity manager to announce its creation.
13584    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13585        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13586        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13587
13588        synchronized(this) {
13589            // !!! TODO: currently no check here that we're already bound
13590            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13591            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13592            synchronized (stats) {
13593                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13594            }
13595
13596            // Backup agent is now in use, its package can't be stopped.
13597            try {
13598                AppGlobals.getPackageManager().setPackageStoppedState(
13599                        app.packageName, false, UserHandle.getUserId(app.uid));
13600            } catch (RemoteException e) {
13601            } catch (IllegalArgumentException e) {
13602                Slog.w(TAG, "Failed trying to unstop package "
13603                        + app.packageName + ": " + e);
13604            }
13605
13606            BackupRecord r = new BackupRecord(ss, app, backupMode);
13607            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13608                    ? new ComponentName(app.packageName, app.backupAgentName)
13609                    : new ComponentName("android", "FullBackupAgent");
13610            // startProcessLocked() returns existing proc's record if it's already running
13611            ProcessRecord proc = startProcessLocked(app.processName, app,
13612                    false, 0, "backup", hostingName, false, false, false);
13613            if (proc == null) {
13614                Slog.e(TAG, "Unable to start backup agent process " + r);
13615                return false;
13616            }
13617
13618            r.app = proc;
13619            mBackupTarget = r;
13620            mBackupAppName = app.packageName;
13621
13622            // Try not to kill the process during backup
13623            updateOomAdjLocked(proc);
13624
13625            // If the process is already attached, schedule the creation of the backup agent now.
13626            // If it is not yet live, this will be done when it attaches to the framework.
13627            if (proc.thread != null) {
13628                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13629                try {
13630                    proc.thread.scheduleCreateBackupAgent(app,
13631                            compatibilityInfoForPackageLocked(app), backupMode);
13632                } catch (RemoteException e) {
13633                    // Will time out on the backup manager side
13634                }
13635            } else {
13636                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13637            }
13638            // Invariants: at this point, the target app process exists and the application
13639            // is either already running or in the process of coming up.  mBackupTarget and
13640            // mBackupAppName describe the app, so that when it binds back to the AM we
13641            // know that it's scheduled for a backup-agent operation.
13642        }
13643
13644        return true;
13645    }
13646
13647    @Override
13648    public void clearPendingBackup() {
13649        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13650        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13651
13652        synchronized (this) {
13653            mBackupTarget = null;
13654            mBackupAppName = null;
13655        }
13656    }
13657
13658    // A backup agent has just come up
13659    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13660        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13661                + " = " + agent);
13662
13663        synchronized(this) {
13664            if (!agentPackageName.equals(mBackupAppName)) {
13665                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13666                return;
13667            }
13668        }
13669
13670        long oldIdent = Binder.clearCallingIdentity();
13671        try {
13672            IBackupManager bm = IBackupManager.Stub.asInterface(
13673                    ServiceManager.getService(Context.BACKUP_SERVICE));
13674            bm.agentConnected(agentPackageName, agent);
13675        } catch (RemoteException e) {
13676            // can't happen; the backup manager service is local
13677        } catch (Exception e) {
13678            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13679            e.printStackTrace();
13680        } finally {
13681            Binder.restoreCallingIdentity(oldIdent);
13682        }
13683    }
13684
13685    // done with this agent
13686    public void unbindBackupAgent(ApplicationInfo appInfo) {
13687        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13688        if (appInfo == null) {
13689            Slog.w(TAG, "unbind backup agent for null app");
13690            return;
13691        }
13692
13693        synchronized(this) {
13694            try {
13695                if (mBackupAppName == null) {
13696                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13697                    return;
13698                }
13699
13700                if (!mBackupAppName.equals(appInfo.packageName)) {
13701                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13702                    return;
13703                }
13704
13705                // Not backing this app up any more; reset its OOM adjustment
13706                final ProcessRecord proc = mBackupTarget.app;
13707                updateOomAdjLocked(proc);
13708
13709                // If the app crashed during backup, 'thread' will be null here
13710                if (proc.thread != null) {
13711                    try {
13712                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13713                                compatibilityInfoForPackageLocked(appInfo));
13714                    } catch (Exception e) {
13715                        Slog.e(TAG, "Exception when unbinding backup agent:");
13716                        e.printStackTrace();
13717                    }
13718                }
13719            } finally {
13720                mBackupTarget = null;
13721                mBackupAppName = null;
13722            }
13723        }
13724    }
13725    // =========================================================
13726    // BROADCASTS
13727    // =========================================================
13728
13729    private final List getStickiesLocked(String action, IntentFilter filter,
13730            List cur, int userId) {
13731        final ContentResolver resolver = mContext.getContentResolver();
13732        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13733        if (stickies == null) {
13734            return cur;
13735        }
13736        final ArrayList<Intent> list = stickies.get(action);
13737        if (list == null) {
13738            return cur;
13739        }
13740        int N = list.size();
13741        for (int i=0; i<N; i++) {
13742            Intent intent = list.get(i);
13743            if (filter.match(resolver, intent, true, TAG) >= 0) {
13744                if (cur == null) {
13745                    cur = new ArrayList<Intent>();
13746                }
13747                cur.add(intent);
13748            }
13749        }
13750        return cur;
13751    }
13752
13753    boolean isPendingBroadcastProcessLocked(int pid) {
13754        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13755                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13756    }
13757
13758    void skipPendingBroadcastLocked(int pid) {
13759            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13760            for (BroadcastQueue queue : mBroadcastQueues) {
13761                queue.skipPendingBroadcastLocked(pid);
13762            }
13763    }
13764
13765    // The app just attached; send any pending broadcasts that it should receive
13766    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13767        boolean didSomething = false;
13768        for (BroadcastQueue queue : mBroadcastQueues) {
13769            didSomething |= queue.sendPendingBroadcastsLocked(app);
13770        }
13771        return didSomething;
13772    }
13773
13774    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13775            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13776        enforceNotIsolatedCaller("registerReceiver");
13777        int callingUid;
13778        int callingPid;
13779        synchronized(this) {
13780            ProcessRecord callerApp = null;
13781            if (caller != null) {
13782                callerApp = getRecordForAppLocked(caller);
13783                if (callerApp == null) {
13784                    throw new SecurityException(
13785                            "Unable to find app for caller " + caller
13786                            + " (pid=" + Binder.getCallingPid()
13787                            + ") when registering receiver " + receiver);
13788                }
13789                if (callerApp.info.uid != Process.SYSTEM_UID &&
13790                        !callerApp.pkgList.containsKey(callerPackage) &&
13791                        !"android".equals(callerPackage)) {
13792                    throw new SecurityException("Given caller package " + callerPackage
13793                            + " is not running in process " + callerApp);
13794                }
13795                callingUid = callerApp.info.uid;
13796                callingPid = callerApp.pid;
13797            } else {
13798                callerPackage = null;
13799                callingUid = Binder.getCallingUid();
13800                callingPid = Binder.getCallingPid();
13801            }
13802
13803            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13804                    true, true, "registerReceiver", callerPackage);
13805
13806            List allSticky = null;
13807
13808            // Look for any matching sticky broadcasts...
13809            Iterator actions = filter.actionsIterator();
13810            if (actions != null) {
13811                while (actions.hasNext()) {
13812                    String action = (String)actions.next();
13813                    allSticky = getStickiesLocked(action, filter, allSticky,
13814                            UserHandle.USER_ALL);
13815                    allSticky = getStickiesLocked(action, filter, allSticky,
13816                            UserHandle.getUserId(callingUid));
13817                }
13818            } else {
13819                allSticky = getStickiesLocked(null, filter, allSticky,
13820                        UserHandle.USER_ALL);
13821                allSticky = getStickiesLocked(null, filter, allSticky,
13822                        UserHandle.getUserId(callingUid));
13823            }
13824
13825            // The first sticky in the list is returned directly back to
13826            // the client.
13827            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13828
13829            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13830                    + ": " + sticky);
13831
13832            if (receiver == null) {
13833                return sticky;
13834            }
13835
13836            ReceiverList rl
13837                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13838            if (rl == null) {
13839                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13840                        userId, receiver);
13841                if (rl.app != null) {
13842                    rl.app.receivers.add(rl);
13843                } else {
13844                    try {
13845                        receiver.asBinder().linkToDeath(rl, 0);
13846                    } catch (RemoteException e) {
13847                        return sticky;
13848                    }
13849                    rl.linkedToDeath = true;
13850                }
13851                mRegisteredReceivers.put(receiver.asBinder(), rl);
13852            } else if (rl.uid != callingUid) {
13853                throw new IllegalArgumentException(
13854                        "Receiver requested to register for uid " + callingUid
13855                        + " was previously registered for uid " + rl.uid);
13856            } else if (rl.pid != callingPid) {
13857                throw new IllegalArgumentException(
13858                        "Receiver requested to register for pid " + callingPid
13859                        + " was previously registered for pid " + rl.pid);
13860            } else if (rl.userId != userId) {
13861                throw new IllegalArgumentException(
13862                        "Receiver requested to register for user " + userId
13863                        + " was previously registered for user " + rl.userId);
13864            }
13865            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13866                    permission, callingUid, userId);
13867            rl.add(bf);
13868            if (!bf.debugCheck()) {
13869                Slog.w(TAG, "==> For Dynamic broadast");
13870            }
13871            mReceiverResolver.addFilter(bf);
13872
13873            // Enqueue broadcasts for all existing stickies that match
13874            // this filter.
13875            if (allSticky != null) {
13876                ArrayList receivers = new ArrayList();
13877                receivers.add(bf);
13878
13879                int N = allSticky.size();
13880                for (int i=0; i<N; i++) {
13881                    Intent intent = (Intent)allSticky.get(i);
13882                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13883                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13884                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13885                            null, null, false, true, true, -1);
13886                    queue.enqueueParallelBroadcastLocked(r);
13887                    queue.scheduleBroadcastsLocked();
13888                }
13889            }
13890
13891            return sticky;
13892        }
13893    }
13894
13895    public void unregisterReceiver(IIntentReceiver receiver) {
13896        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13897
13898        final long origId = Binder.clearCallingIdentity();
13899        try {
13900            boolean doTrim = false;
13901
13902            synchronized(this) {
13903                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13904                if (rl != null) {
13905                    if (rl.curBroadcast != null) {
13906                        BroadcastRecord r = rl.curBroadcast;
13907                        final boolean doNext = finishReceiverLocked(
13908                                receiver.asBinder(), r.resultCode, r.resultData,
13909                                r.resultExtras, r.resultAbort);
13910                        if (doNext) {
13911                            doTrim = true;
13912                            r.queue.processNextBroadcast(false);
13913                        }
13914                    }
13915
13916                    if (rl.app != null) {
13917                        rl.app.receivers.remove(rl);
13918                    }
13919                    removeReceiverLocked(rl);
13920                    if (rl.linkedToDeath) {
13921                        rl.linkedToDeath = false;
13922                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13923                    }
13924                }
13925            }
13926
13927            // If we actually concluded any broadcasts, we might now be able
13928            // to trim the recipients' apps from our working set
13929            if (doTrim) {
13930                trimApplications();
13931                return;
13932            }
13933
13934        } finally {
13935            Binder.restoreCallingIdentity(origId);
13936        }
13937    }
13938
13939    void removeReceiverLocked(ReceiverList rl) {
13940        mRegisteredReceivers.remove(rl.receiver.asBinder());
13941        int N = rl.size();
13942        for (int i=0; i<N; i++) {
13943            mReceiverResolver.removeFilter(rl.get(i));
13944        }
13945    }
13946
13947    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13948        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13949            ProcessRecord r = mLruProcesses.get(i);
13950            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13951                try {
13952                    r.thread.dispatchPackageBroadcast(cmd, packages);
13953                } catch (RemoteException ex) {
13954                }
13955            }
13956        }
13957    }
13958
13959    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13960            int[] users) {
13961        List<ResolveInfo> receivers = null;
13962        try {
13963            HashSet<ComponentName> singleUserReceivers = null;
13964            boolean scannedFirstReceivers = false;
13965            for (int user : users) {
13966                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13967                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13968                if (user != 0 && newReceivers != null) {
13969                    // If this is not the primary user, we need to check for
13970                    // any receivers that should be filtered out.
13971                    for (int i=0; i<newReceivers.size(); i++) {
13972                        ResolveInfo ri = newReceivers.get(i);
13973                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13974                            newReceivers.remove(i);
13975                            i--;
13976                        }
13977                    }
13978                }
13979                if (newReceivers != null && newReceivers.size() == 0) {
13980                    newReceivers = null;
13981                }
13982                if (receivers == null) {
13983                    receivers = newReceivers;
13984                } else if (newReceivers != null) {
13985                    // We need to concatenate the additional receivers
13986                    // found with what we have do far.  This would be easy,
13987                    // but we also need to de-dup any receivers that are
13988                    // singleUser.
13989                    if (!scannedFirstReceivers) {
13990                        // Collect any single user receivers we had already retrieved.
13991                        scannedFirstReceivers = true;
13992                        for (int i=0; i<receivers.size(); i++) {
13993                            ResolveInfo ri = receivers.get(i);
13994                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13995                                ComponentName cn = new ComponentName(
13996                                        ri.activityInfo.packageName, ri.activityInfo.name);
13997                                if (singleUserReceivers == null) {
13998                                    singleUserReceivers = new HashSet<ComponentName>();
13999                                }
14000                                singleUserReceivers.add(cn);
14001                            }
14002                        }
14003                    }
14004                    // Add the new results to the existing results, tracking
14005                    // and de-dupping single user receivers.
14006                    for (int i=0; i<newReceivers.size(); i++) {
14007                        ResolveInfo ri = newReceivers.get(i);
14008                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14009                            ComponentName cn = new ComponentName(
14010                                    ri.activityInfo.packageName, ri.activityInfo.name);
14011                            if (singleUserReceivers == null) {
14012                                singleUserReceivers = new HashSet<ComponentName>();
14013                            }
14014                            if (!singleUserReceivers.contains(cn)) {
14015                                singleUserReceivers.add(cn);
14016                                receivers.add(ri);
14017                            }
14018                        } else {
14019                            receivers.add(ri);
14020                        }
14021                    }
14022                }
14023            }
14024        } catch (RemoteException ex) {
14025            // pm is in same process, this will never happen.
14026        }
14027        return receivers;
14028    }
14029
14030    private final int broadcastIntentLocked(ProcessRecord callerApp,
14031            String callerPackage, Intent intent, String resolvedType,
14032            IIntentReceiver resultTo, int resultCode, String resultData,
14033            Bundle map, String requiredPermission, int appOp,
14034            boolean ordered, boolean sticky, int callingPid, int callingUid,
14035            int userId) {
14036        intent = new Intent(intent);
14037
14038        // By default broadcasts do not go to stopped apps.
14039        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14040
14041        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14042            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14043            + " ordered=" + ordered + " userid=" + userId);
14044        if ((resultTo != null) && !ordered) {
14045            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14046        }
14047
14048        userId = handleIncomingUser(callingPid, callingUid, userId,
14049                true, false, "broadcast", callerPackage);
14050
14051        // Make sure that the user who is receiving this broadcast is started.
14052        // If not, we will just skip it.
14053
14054
14055        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14056            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14057                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14058                Slog.w(TAG, "Skipping broadcast of " + intent
14059                        + ": user " + userId + " is stopped");
14060                return ActivityManager.BROADCAST_SUCCESS;
14061            }
14062        }
14063
14064        /*
14065         * Prevent non-system code (defined here to be non-persistent
14066         * processes) from sending protected broadcasts.
14067         */
14068        int callingAppId = UserHandle.getAppId(callingUid);
14069        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14070            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14071            || callingAppId == Process.NFC_UID || callingUid == 0) {
14072            // Always okay.
14073        } else if (callerApp == null || !callerApp.persistent) {
14074            try {
14075                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14076                        intent.getAction())) {
14077                    String msg = "Permission Denial: not allowed to send broadcast "
14078                            + intent.getAction() + " from pid="
14079                            + callingPid + ", uid=" + callingUid;
14080                    Slog.w(TAG, msg);
14081                    throw new SecurityException(msg);
14082                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14083                    // Special case for compatibility: we don't want apps to send this,
14084                    // but historically it has not been protected and apps may be using it
14085                    // to poke their own app widget.  So, instead of making it protected,
14086                    // just limit it to the caller.
14087                    if (callerApp == null) {
14088                        String msg = "Permission Denial: not allowed to send broadcast "
14089                                + intent.getAction() + " from unknown caller.";
14090                        Slog.w(TAG, msg);
14091                        throw new SecurityException(msg);
14092                    } else if (intent.getComponent() != null) {
14093                        // They are good enough to send to an explicit component...  verify
14094                        // it is being sent to the calling app.
14095                        if (!intent.getComponent().getPackageName().equals(
14096                                callerApp.info.packageName)) {
14097                            String msg = "Permission Denial: not allowed to send broadcast "
14098                                    + intent.getAction() + " to "
14099                                    + intent.getComponent().getPackageName() + " from "
14100                                    + callerApp.info.packageName;
14101                            Slog.w(TAG, msg);
14102                            throw new SecurityException(msg);
14103                        }
14104                    } else {
14105                        // Limit broadcast to their own package.
14106                        intent.setPackage(callerApp.info.packageName);
14107                    }
14108                }
14109            } catch (RemoteException e) {
14110                Slog.w(TAG, "Remote exception", e);
14111                return ActivityManager.BROADCAST_SUCCESS;
14112            }
14113        }
14114
14115        // Handle special intents: if this broadcast is from the package
14116        // manager about a package being removed, we need to remove all of
14117        // its activities from the history stack.
14118        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14119                intent.getAction());
14120        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14121                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14122                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14123                || uidRemoved) {
14124            if (checkComponentPermission(
14125                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14126                    callingPid, callingUid, -1, true)
14127                    == PackageManager.PERMISSION_GRANTED) {
14128                if (uidRemoved) {
14129                    final Bundle intentExtras = intent.getExtras();
14130                    final int uid = intentExtras != null
14131                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14132                    if (uid >= 0) {
14133                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14134                        synchronized (bs) {
14135                            bs.removeUidStatsLocked(uid);
14136                        }
14137                        mAppOpsService.uidRemoved(uid);
14138                    }
14139                } else {
14140                    // If resources are unavailable just force stop all
14141                    // those packages and flush the attribute cache as well.
14142                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14143                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14144                        if (list != null && (list.length > 0)) {
14145                            for (String pkg : list) {
14146                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14147                                        "storage unmount");
14148                            }
14149                            sendPackageBroadcastLocked(
14150                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14151                        }
14152                    } else {
14153                        Uri data = intent.getData();
14154                        String ssp;
14155                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14156                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14157                                    intent.getAction());
14158                            boolean fullUninstall = removed &&
14159                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14160                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14161                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14162                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14163                                        false, fullUninstall, userId,
14164                                        removed ? "pkg removed" : "pkg changed");
14165                            }
14166                            if (removed) {
14167                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14168                                        new String[] {ssp}, userId);
14169                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14170                                    mAppOpsService.packageRemoved(
14171                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14172
14173                                    // Remove all permissions granted from/to this package
14174                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14175                                }
14176                            }
14177                        }
14178                    }
14179                }
14180            } else {
14181                String msg = "Permission Denial: " + intent.getAction()
14182                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14183                        + ", uid=" + callingUid + ")"
14184                        + " requires "
14185                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14186                Slog.w(TAG, msg);
14187                throw new SecurityException(msg);
14188            }
14189
14190        // Special case for adding a package: by default turn on compatibility
14191        // mode.
14192        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14193            Uri data = intent.getData();
14194            String ssp;
14195            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14196                mCompatModePackages.handlePackageAddedLocked(ssp,
14197                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14198            }
14199        }
14200
14201        /*
14202         * If this is the time zone changed action, queue up a message that will reset the timezone
14203         * of all currently running processes. This message will get queued up before the broadcast
14204         * happens.
14205         */
14206        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14207            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14208        }
14209
14210        /*
14211         * If the user set the time, let all running processes know.
14212         */
14213        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14214            final int is24Hour = intent.getBooleanExtra(
14215                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14216            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14217        }
14218
14219        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14220            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14221        }
14222
14223        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14224            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14225            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14226        }
14227
14228        // Add to the sticky list if requested.
14229        if (sticky) {
14230            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14231                    callingPid, callingUid)
14232                    != PackageManager.PERMISSION_GRANTED) {
14233                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14234                        + callingPid + ", uid=" + callingUid
14235                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14236                Slog.w(TAG, msg);
14237                throw new SecurityException(msg);
14238            }
14239            if (requiredPermission != null) {
14240                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14241                        + " and enforce permission " + requiredPermission);
14242                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14243            }
14244            if (intent.getComponent() != null) {
14245                throw new SecurityException(
14246                        "Sticky broadcasts can't target a specific component");
14247            }
14248            // We use userId directly here, since the "all" target is maintained
14249            // as a separate set of sticky broadcasts.
14250            if (userId != UserHandle.USER_ALL) {
14251                // But first, if this is not a broadcast to all users, then
14252                // make sure it doesn't conflict with an existing broadcast to
14253                // all users.
14254                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14255                        UserHandle.USER_ALL);
14256                if (stickies != null) {
14257                    ArrayList<Intent> list = stickies.get(intent.getAction());
14258                    if (list != null) {
14259                        int N = list.size();
14260                        int i;
14261                        for (i=0; i<N; i++) {
14262                            if (intent.filterEquals(list.get(i))) {
14263                                throw new IllegalArgumentException(
14264                                        "Sticky broadcast " + intent + " for user "
14265                                        + userId + " conflicts with existing global broadcast");
14266                            }
14267                        }
14268                    }
14269                }
14270            }
14271            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14272            if (stickies == null) {
14273                stickies = new ArrayMap<String, ArrayList<Intent>>();
14274                mStickyBroadcasts.put(userId, stickies);
14275            }
14276            ArrayList<Intent> list = stickies.get(intent.getAction());
14277            if (list == null) {
14278                list = new ArrayList<Intent>();
14279                stickies.put(intent.getAction(), list);
14280            }
14281            int N = list.size();
14282            int i;
14283            for (i=0; i<N; i++) {
14284                if (intent.filterEquals(list.get(i))) {
14285                    // This sticky already exists, replace it.
14286                    list.set(i, new Intent(intent));
14287                    break;
14288                }
14289            }
14290            if (i >= N) {
14291                list.add(new Intent(intent));
14292            }
14293        }
14294
14295        int[] users;
14296        if (userId == UserHandle.USER_ALL) {
14297            // Caller wants broadcast to go to all started users.
14298            users = mStartedUserArray;
14299        } else {
14300            // Caller wants broadcast to go to one specific user.
14301            users = new int[] {userId};
14302        }
14303
14304        // Figure out who all will receive this broadcast.
14305        List receivers = null;
14306        List<BroadcastFilter> registeredReceivers = null;
14307        // Need to resolve the intent to interested receivers...
14308        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14309                 == 0) {
14310            receivers = collectReceiverComponents(intent, resolvedType, users);
14311        }
14312        if (intent.getComponent() == null) {
14313            registeredReceivers = mReceiverResolver.queryIntent(intent,
14314                    resolvedType, false, userId);
14315        }
14316
14317        final boolean replacePending =
14318                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14319
14320        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14321                + " replacePending=" + replacePending);
14322
14323        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14324        if (!ordered && NR > 0) {
14325            // If we are not serializing this broadcast, then send the
14326            // registered receivers separately so they don't wait for the
14327            // components to be launched.
14328            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14329            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14330                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14331                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14332                    ordered, sticky, false, userId);
14333            if (DEBUG_BROADCAST) Slog.v(
14334                    TAG, "Enqueueing parallel broadcast " + r);
14335            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14336            if (!replaced) {
14337                queue.enqueueParallelBroadcastLocked(r);
14338                queue.scheduleBroadcastsLocked();
14339            }
14340            registeredReceivers = null;
14341            NR = 0;
14342        }
14343
14344        // Merge into one list.
14345        int ir = 0;
14346        if (receivers != null) {
14347            // A special case for PACKAGE_ADDED: do not allow the package
14348            // being added to see this broadcast.  This prevents them from
14349            // using this as a back door to get run as soon as they are
14350            // installed.  Maybe in the future we want to have a special install
14351            // broadcast or such for apps, but we'd like to deliberately make
14352            // this decision.
14353            String skipPackages[] = null;
14354            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14355                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14356                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14357                Uri data = intent.getData();
14358                if (data != null) {
14359                    String pkgName = data.getSchemeSpecificPart();
14360                    if (pkgName != null) {
14361                        skipPackages = new String[] { pkgName };
14362                    }
14363                }
14364            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14365                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14366            }
14367            if (skipPackages != null && (skipPackages.length > 0)) {
14368                for (String skipPackage : skipPackages) {
14369                    if (skipPackage != null) {
14370                        int NT = receivers.size();
14371                        for (int it=0; it<NT; it++) {
14372                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14373                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14374                                receivers.remove(it);
14375                                it--;
14376                                NT--;
14377                            }
14378                        }
14379                    }
14380                }
14381            }
14382
14383            int NT = receivers != null ? receivers.size() : 0;
14384            int it = 0;
14385            ResolveInfo curt = null;
14386            BroadcastFilter curr = null;
14387            while (it < NT && ir < NR) {
14388                if (curt == null) {
14389                    curt = (ResolveInfo)receivers.get(it);
14390                }
14391                if (curr == null) {
14392                    curr = registeredReceivers.get(ir);
14393                }
14394                if (curr.getPriority() >= curt.priority) {
14395                    // Insert this broadcast record into the final list.
14396                    receivers.add(it, curr);
14397                    ir++;
14398                    curr = null;
14399                    it++;
14400                    NT++;
14401                } else {
14402                    // Skip to the next ResolveInfo in the final list.
14403                    it++;
14404                    curt = null;
14405                }
14406            }
14407        }
14408        while (ir < NR) {
14409            if (receivers == null) {
14410                receivers = new ArrayList();
14411            }
14412            receivers.add(registeredReceivers.get(ir));
14413            ir++;
14414        }
14415
14416        if ((receivers != null && receivers.size() > 0)
14417                || resultTo != null) {
14418            BroadcastQueue queue = broadcastQueueForIntent(intent);
14419            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14420                    callerPackage, callingPid, callingUid, resolvedType,
14421                    requiredPermission, appOp, receivers, resultTo, resultCode,
14422                    resultData, map, ordered, sticky, false, userId);
14423            if (DEBUG_BROADCAST) Slog.v(
14424                    TAG, "Enqueueing ordered broadcast " + r
14425                    + ": prev had " + queue.mOrderedBroadcasts.size());
14426            if (DEBUG_BROADCAST) {
14427                int seq = r.intent.getIntExtra("seq", -1);
14428                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14429            }
14430            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14431            if (!replaced) {
14432                queue.enqueueOrderedBroadcastLocked(r);
14433                queue.scheduleBroadcastsLocked();
14434            }
14435        }
14436
14437        return ActivityManager.BROADCAST_SUCCESS;
14438    }
14439
14440    final Intent verifyBroadcastLocked(Intent intent) {
14441        // Refuse possible leaked file descriptors
14442        if (intent != null && intent.hasFileDescriptors() == true) {
14443            throw new IllegalArgumentException("File descriptors passed in Intent");
14444        }
14445
14446        int flags = intent.getFlags();
14447
14448        if (!mProcessesReady) {
14449            // if the caller really truly claims to know what they're doing, go
14450            // ahead and allow the broadcast without launching any receivers
14451            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14452                intent = new Intent(intent);
14453                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14454            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14455                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14456                        + " before boot completion");
14457                throw new IllegalStateException("Cannot broadcast before boot completed");
14458            }
14459        }
14460
14461        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14462            throw new IllegalArgumentException(
14463                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14464        }
14465
14466        return intent;
14467    }
14468
14469    public final int broadcastIntent(IApplicationThread caller,
14470            Intent intent, String resolvedType, IIntentReceiver resultTo,
14471            int resultCode, String resultData, Bundle map,
14472            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14473        enforceNotIsolatedCaller("broadcastIntent");
14474        synchronized(this) {
14475            intent = verifyBroadcastLocked(intent);
14476
14477            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14478            final int callingPid = Binder.getCallingPid();
14479            final int callingUid = Binder.getCallingUid();
14480            final long origId = Binder.clearCallingIdentity();
14481            int res = broadcastIntentLocked(callerApp,
14482                    callerApp != null ? callerApp.info.packageName : null,
14483                    intent, resolvedType, resultTo,
14484                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14485                    callingPid, callingUid, userId);
14486            Binder.restoreCallingIdentity(origId);
14487            return res;
14488        }
14489    }
14490
14491    int broadcastIntentInPackage(String packageName, int uid,
14492            Intent intent, String resolvedType, IIntentReceiver resultTo,
14493            int resultCode, String resultData, Bundle map,
14494            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14495        synchronized(this) {
14496            intent = verifyBroadcastLocked(intent);
14497
14498            final long origId = Binder.clearCallingIdentity();
14499            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14500                    resultTo, resultCode, resultData, map, requiredPermission,
14501                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14502            Binder.restoreCallingIdentity(origId);
14503            return res;
14504        }
14505    }
14506
14507    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14508        // Refuse possible leaked file descriptors
14509        if (intent != null && intent.hasFileDescriptors() == true) {
14510            throw new IllegalArgumentException("File descriptors passed in Intent");
14511        }
14512
14513        userId = handleIncomingUser(Binder.getCallingPid(),
14514                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14515
14516        synchronized(this) {
14517            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14518                    != PackageManager.PERMISSION_GRANTED) {
14519                String msg = "Permission Denial: unbroadcastIntent() from pid="
14520                        + Binder.getCallingPid()
14521                        + ", uid=" + Binder.getCallingUid()
14522                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14523                Slog.w(TAG, msg);
14524                throw new SecurityException(msg);
14525            }
14526            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14527            if (stickies != null) {
14528                ArrayList<Intent> list = stickies.get(intent.getAction());
14529                if (list != null) {
14530                    int N = list.size();
14531                    int i;
14532                    for (i=0; i<N; i++) {
14533                        if (intent.filterEquals(list.get(i))) {
14534                            list.remove(i);
14535                            break;
14536                        }
14537                    }
14538                    if (list.size() <= 0) {
14539                        stickies.remove(intent.getAction());
14540                    }
14541                }
14542                if (stickies.size() <= 0) {
14543                    mStickyBroadcasts.remove(userId);
14544                }
14545            }
14546        }
14547    }
14548
14549    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14550            String resultData, Bundle resultExtras, boolean resultAbort) {
14551        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14552        if (r == null) {
14553            Slog.w(TAG, "finishReceiver called but not found on queue");
14554            return false;
14555        }
14556
14557        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14558    }
14559
14560    void backgroundServicesFinishedLocked(int userId) {
14561        for (BroadcastQueue queue : mBroadcastQueues) {
14562            queue.backgroundServicesFinishedLocked(userId);
14563        }
14564    }
14565
14566    public void finishReceiver(IBinder who, int resultCode, String resultData,
14567            Bundle resultExtras, boolean resultAbort) {
14568        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14569
14570        // Refuse possible leaked file descriptors
14571        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14572            throw new IllegalArgumentException("File descriptors passed in Bundle");
14573        }
14574
14575        final long origId = Binder.clearCallingIdentity();
14576        try {
14577            boolean doNext = false;
14578            BroadcastRecord r;
14579
14580            synchronized(this) {
14581                r = broadcastRecordForReceiverLocked(who);
14582                if (r != null) {
14583                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14584                        resultData, resultExtras, resultAbort, true);
14585                }
14586            }
14587
14588            if (doNext) {
14589                r.queue.processNextBroadcast(false);
14590            }
14591            trimApplications();
14592        } finally {
14593            Binder.restoreCallingIdentity(origId);
14594        }
14595    }
14596
14597    // =========================================================
14598    // INSTRUMENTATION
14599    // =========================================================
14600
14601    public boolean startInstrumentation(ComponentName className,
14602            String profileFile, int flags, Bundle arguments,
14603            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14604            int userId, String abiOverride) {
14605        enforceNotIsolatedCaller("startInstrumentation");
14606        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14607                userId, false, true, "startInstrumentation", null);
14608        // Refuse possible leaked file descriptors
14609        if (arguments != null && arguments.hasFileDescriptors()) {
14610            throw new IllegalArgumentException("File descriptors passed in Bundle");
14611        }
14612
14613        synchronized(this) {
14614            InstrumentationInfo ii = null;
14615            ApplicationInfo ai = null;
14616            try {
14617                ii = mContext.getPackageManager().getInstrumentationInfo(
14618                    className, STOCK_PM_FLAGS);
14619                ai = AppGlobals.getPackageManager().getApplicationInfo(
14620                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14621            } catch (PackageManager.NameNotFoundException e) {
14622            } catch (RemoteException e) {
14623            }
14624            if (ii == null) {
14625                reportStartInstrumentationFailure(watcher, className,
14626                        "Unable to find instrumentation info for: " + className);
14627                return false;
14628            }
14629            if (ai == null) {
14630                reportStartInstrumentationFailure(watcher, className,
14631                        "Unable to find instrumentation target package: " + ii.targetPackage);
14632                return false;
14633            }
14634
14635            int match = mContext.getPackageManager().checkSignatures(
14636                    ii.targetPackage, ii.packageName);
14637            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14638                String msg = "Permission Denial: starting instrumentation "
14639                        + className + " from pid="
14640                        + Binder.getCallingPid()
14641                        + ", uid=" + Binder.getCallingPid()
14642                        + " not allowed because package " + ii.packageName
14643                        + " does not have a signature matching the target "
14644                        + ii.targetPackage;
14645                reportStartInstrumentationFailure(watcher, className, msg);
14646                throw new SecurityException(msg);
14647            }
14648
14649            final long origId = Binder.clearCallingIdentity();
14650            // Instrumentation can kill and relaunch even persistent processes
14651            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14652                    "start instr");
14653            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14654            app.instrumentationClass = className;
14655            app.instrumentationInfo = ai;
14656            app.instrumentationProfileFile = profileFile;
14657            app.instrumentationArguments = arguments;
14658            app.instrumentationWatcher = watcher;
14659            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14660            app.instrumentationResultClass = className;
14661            Binder.restoreCallingIdentity(origId);
14662        }
14663
14664        return true;
14665    }
14666
14667    /**
14668     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14669     * error to the logs, but if somebody is watching, send the report there too.  This enables
14670     * the "am" command to report errors with more information.
14671     *
14672     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14673     * @param cn The component name of the instrumentation.
14674     * @param report The error report.
14675     */
14676    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14677            ComponentName cn, String report) {
14678        Slog.w(TAG, report);
14679        try {
14680            if (watcher != null) {
14681                Bundle results = new Bundle();
14682                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14683                results.putString("Error", report);
14684                watcher.instrumentationStatus(cn, -1, results);
14685            }
14686        } catch (RemoteException e) {
14687            Slog.w(TAG, e);
14688        }
14689    }
14690
14691    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14692        if (app.instrumentationWatcher != null) {
14693            try {
14694                // NOTE:  IInstrumentationWatcher *must* be oneway here
14695                app.instrumentationWatcher.instrumentationFinished(
14696                    app.instrumentationClass,
14697                    resultCode,
14698                    results);
14699            } catch (RemoteException e) {
14700            }
14701        }
14702        if (app.instrumentationUiAutomationConnection != null) {
14703            try {
14704                app.instrumentationUiAutomationConnection.shutdown();
14705            } catch (RemoteException re) {
14706                /* ignore */
14707            }
14708            // Only a UiAutomation can set this flag and now that
14709            // it is finished we make sure it is reset to its default.
14710            mUserIsMonkey = false;
14711        }
14712        app.instrumentationWatcher = null;
14713        app.instrumentationUiAutomationConnection = null;
14714        app.instrumentationClass = null;
14715        app.instrumentationInfo = null;
14716        app.instrumentationProfileFile = null;
14717        app.instrumentationArguments = null;
14718
14719        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14720                "finished inst");
14721    }
14722
14723    public void finishInstrumentation(IApplicationThread target,
14724            int resultCode, Bundle results) {
14725        int userId = UserHandle.getCallingUserId();
14726        // Refuse possible leaked file descriptors
14727        if (results != null && results.hasFileDescriptors()) {
14728            throw new IllegalArgumentException("File descriptors passed in Intent");
14729        }
14730
14731        synchronized(this) {
14732            ProcessRecord app = getRecordForAppLocked(target);
14733            if (app == null) {
14734                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14735                return;
14736            }
14737            final long origId = Binder.clearCallingIdentity();
14738            finishInstrumentationLocked(app, resultCode, results);
14739            Binder.restoreCallingIdentity(origId);
14740        }
14741    }
14742
14743    // =========================================================
14744    // CONFIGURATION
14745    // =========================================================
14746
14747    public ConfigurationInfo getDeviceConfigurationInfo() {
14748        ConfigurationInfo config = new ConfigurationInfo();
14749        synchronized (this) {
14750            config.reqTouchScreen = mConfiguration.touchscreen;
14751            config.reqKeyboardType = mConfiguration.keyboard;
14752            config.reqNavigation = mConfiguration.navigation;
14753            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14754                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14755                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14756            }
14757            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14758                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14759                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14760            }
14761            config.reqGlEsVersion = GL_ES_VERSION;
14762        }
14763        return config;
14764    }
14765
14766    ActivityStack getFocusedStack() {
14767        return mStackSupervisor.getFocusedStack();
14768    }
14769
14770    public Configuration getConfiguration() {
14771        Configuration ci;
14772        synchronized(this) {
14773            ci = new Configuration(mConfiguration);
14774        }
14775        return ci;
14776    }
14777
14778    public void updatePersistentConfiguration(Configuration values) {
14779        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14780                "updateConfiguration()");
14781        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14782                "updateConfiguration()");
14783        if (values == null) {
14784            throw new NullPointerException("Configuration must not be null");
14785        }
14786
14787        synchronized(this) {
14788            final long origId = Binder.clearCallingIdentity();
14789            updateConfigurationLocked(values, null, true, false);
14790            Binder.restoreCallingIdentity(origId);
14791        }
14792    }
14793
14794    public void updateConfiguration(Configuration values) {
14795        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14796                "updateConfiguration()");
14797
14798        synchronized(this) {
14799            if (values == null && mWindowManager != null) {
14800                // sentinel: fetch the current configuration from the window manager
14801                values = mWindowManager.computeNewConfiguration();
14802            }
14803
14804            if (mWindowManager != null) {
14805                mProcessList.applyDisplaySize(mWindowManager);
14806            }
14807
14808            final long origId = Binder.clearCallingIdentity();
14809            if (values != null) {
14810                Settings.System.clearConfiguration(values);
14811            }
14812            updateConfigurationLocked(values, null, false, false);
14813            Binder.restoreCallingIdentity(origId);
14814        }
14815    }
14816
14817    /**
14818     * Do either or both things: (1) change the current configuration, and (2)
14819     * make sure the given activity is running with the (now) current
14820     * configuration.  Returns true if the activity has been left running, or
14821     * false if <var>starting</var> is being destroyed to match the new
14822     * configuration.
14823     * @param persistent TODO
14824     */
14825    boolean updateConfigurationLocked(Configuration values,
14826            ActivityRecord starting, boolean persistent, boolean initLocale) {
14827        int changes = 0;
14828
14829        if (values != null) {
14830            Configuration newConfig = new Configuration(mConfiguration);
14831            changes = newConfig.updateFrom(values);
14832            if (changes != 0) {
14833                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14834                    Slog.i(TAG, "Updating configuration to: " + values);
14835                }
14836
14837                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14838
14839                if (values.locale != null && !initLocale) {
14840                    saveLocaleLocked(values.locale,
14841                                     !values.locale.equals(mConfiguration.locale),
14842                                     values.userSetLocale);
14843                }
14844
14845                mConfigurationSeq++;
14846                if (mConfigurationSeq <= 0) {
14847                    mConfigurationSeq = 1;
14848                }
14849                newConfig.seq = mConfigurationSeq;
14850                mConfiguration = newConfig;
14851                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14852                mUsageStatsService.noteStartConfig(newConfig);
14853
14854                final Configuration configCopy = new Configuration(mConfiguration);
14855
14856                // TODO: If our config changes, should we auto dismiss any currently
14857                // showing dialogs?
14858                mShowDialogs = shouldShowDialogs(newConfig);
14859
14860                AttributeCache ac = AttributeCache.instance();
14861                if (ac != null) {
14862                    ac.updateConfiguration(configCopy);
14863                }
14864
14865                // Make sure all resources in our process are updated
14866                // right now, so that anyone who is going to retrieve
14867                // resource values after we return will be sure to get
14868                // the new ones.  This is especially important during
14869                // boot, where the first config change needs to guarantee
14870                // all resources have that config before following boot
14871                // code is executed.
14872                mSystemThread.applyConfigurationToResources(configCopy);
14873
14874                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14875                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14876                    msg.obj = new Configuration(configCopy);
14877                    mHandler.sendMessage(msg);
14878                }
14879
14880                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14881                    ProcessRecord app = mLruProcesses.get(i);
14882                    try {
14883                        if (app.thread != null) {
14884                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14885                                    + app.processName + " new config " + mConfiguration);
14886                            app.thread.scheduleConfigurationChanged(configCopy);
14887                        }
14888                    } catch (Exception e) {
14889                    }
14890                }
14891                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14892                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14893                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14894                        | Intent.FLAG_RECEIVER_FOREGROUND);
14895                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14896                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14897                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14898                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14899                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14900                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14901                    broadcastIntentLocked(null, null, intent,
14902                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14903                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14904                }
14905            }
14906        }
14907
14908        boolean kept = true;
14909        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14910        // mainStack is null during startup.
14911        if (mainStack != null) {
14912            if (changes != 0 && starting == null) {
14913                // If the configuration changed, and the caller is not already
14914                // in the process of starting an activity, then find the top
14915                // activity to check if its configuration needs to change.
14916                starting = mainStack.topRunningActivityLocked(null);
14917            }
14918
14919            if (starting != null) {
14920                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14921                // And we need to make sure at this point that all other activities
14922                // are made visible with the correct configuration.
14923                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14924            }
14925        }
14926
14927        if (values != null && mWindowManager != null) {
14928            mWindowManager.setNewConfiguration(mConfiguration);
14929        }
14930
14931        return kept;
14932    }
14933
14934    /**
14935     * Decide based on the configuration whether we should shouw the ANR,
14936     * crash, etc dialogs.  The idea is that if there is no affordnace to
14937     * press the on-screen buttons, we shouldn't show the dialog.
14938     *
14939     * A thought: SystemUI might also want to get told about this, the Power
14940     * dialog / global actions also might want different behaviors.
14941     */
14942    private static final boolean shouldShowDialogs(Configuration config) {
14943        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14944                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14945    }
14946
14947    /**
14948     * Save the locale.  You must be inside a synchronized (this) block.
14949     */
14950    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14951        if(isDiff) {
14952            SystemProperties.set("user.language", l.getLanguage());
14953            SystemProperties.set("user.region", l.getCountry());
14954        }
14955
14956        if(isPersist) {
14957            SystemProperties.set("persist.sys.language", l.getLanguage());
14958            SystemProperties.set("persist.sys.country", l.getCountry());
14959            SystemProperties.set("persist.sys.localevar", l.getVariant());
14960        }
14961    }
14962
14963    @Override
14964    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14965        ActivityRecord srec = ActivityRecord.forToken(token);
14966        return srec != null && srec.task.affinity != null &&
14967                srec.task.affinity.equals(destAffinity);
14968    }
14969
14970    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14971            Intent resultData) {
14972
14973        synchronized (this) {
14974            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14975            if (stack != null) {
14976                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14977            }
14978            return false;
14979        }
14980    }
14981
14982    public int getLaunchedFromUid(IBinder activityToken) {
14983        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14984        if (srec == null) {
14985            return -1;
14986        }
14987        return srec.launchedFromUid;
14988    }
14989
14990    public String getLaunchedFromPackage(IBinder activityToken) {
14991        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14992        if (srec == null) {
14993            return null;
14994        }
14995        return srec.launchedFromPackage;
14996    }
14997
14998    // =========================================================
14999    // LIFETIME MANAGEMENT
15000    // =========================================================
15001
15002    // Returns which broadcast queue the app is the current [or imminent] receiver
15003    // on, or 'null' if the app is not an active broadcast recipient.
15004    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15005        BroadcastRecord r = app.curReceiver;
15006        if (r != null) {
15007            return r.queue;
15008        }
15009
15010        // It's not the current receiver, but it might be starting up to become one
15011        synchronized (this) {
15012            for (BroadcastQueue queue : mBroadcastQueues) {
15013                r = queue.mPendingBroadcast;
15014                if (r != null && r.curApp == app) {
15015                    // found it; report which queue it's in
15016                    return queue;
15017                }
15018            }
15019        }
15020
15021        return null;
15022    }
15023
15024    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15025            boolean doingAll, long now) {
15026        if (mAdjSeq == app.adjSeq) {
15027            // This adjustment has already been computed.
15028            return app.curRawAdj;
15029        }
15030
15031        if (app.thread == null) {
15032            app.adjSeq = mAdjSeq;
15033            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15034            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15035            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15036        }
15037
15038        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15039        app.adjSource = null;
15040        app.adjTarget = null;
15041        app.empty = false;
15042        app.cached = false;
15043
15044        final int activitiesSize = app.activities.size();
15045
15046        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15047            // The max adjustment doesn't allow this app to be anything
15048            // below foreground, so it is not worth doing work for it.
15049            app.adjType = "fixed";
15050            app.adjSeq = mAdjSeq;
15051            app.curRawAdj = app.maxAdj;
15052            app.foregroundActivities = false;
15053            app.keeping = true;
15054            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15055            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15056            // System processes can do UI, and when they do we want to have
15057            // them trim their memory after the user leaves the UI.  To
15058            // facilitate this, here we need to determine whether or not it
15059            // is currently showing UI.
15060            app.systemNoUi = true;
15061            if (app == TOP_APP) {
15062                app.systemNoUi = false;
15063            } else if (activitiesSize > 0) {
15064                for (int j = 0; j < activitiesSize; j++) {
15065                    final ActivityRecord r = app.activities.get(j);
15066                    if (r.visible) {
15067                        app.systemNoUi = false;
15068                    }
15069                }
15070            }
15071            if (!app.systemNoUi) {
15072                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15073            }
15074            return (app.curAdj=app.maxAdj);
15075        }
15076
15077        app.keeping = false;
15078        app.systemNoUi = false;
15079
15080        // Determine the importance of the process, starting with most
15081        // important to least, and assign an appropriate OOM adjustment.
15082        int adj;
15083        int schedGroup;
15084        int procState;
15085        boolean foregroundActivities = false;
15086        BroadcastQueue queue;
15087        if (app == TOP_APP) {
15088            // The last app on the list is the foreground app.
15089            adj = ProcessList.FOREGROUND_APP_ADJ;
15090            schedGroup = Process.THREAD_GROUP_DEFAULT;
15091            app.adjType = "top-activity";
15092            foregroundActivities = true;
15093            procState = ActivityManager.PROCESS_STATE_TOP;
15094        } else if (app.instrumentationClass != null) {
15095            // Don't want to kill running instrumentation.
15096            adj = ProcessList.FOREGROUND_APP_ADJ;
15097            schedGroup = Process.THREAD_GROUP_DEFAULT;
15098            app.adjType = "instrumentation";
15099            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15100        } else if ((queue = isReceivingBroadcast(app)) != null) {
15101            // An app that is currently receiving a broadcast also
15102            // counts as being in the foreground for OOM killer purposes.
15103            // It's placed in a sched group based on the nature of the
15104            // broadcast as reflected by which queue it's active in.
15105            adj = ProcessList.FOREGROUND_APP_ADJ;
15106            schedGroup = (queue == mFgBroadcastQueue)
15107                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15108            app.adjType = "broadcast";
15109            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15110        } else if (app.executingServices.size() > 0) {
15111            // An app that is currently executing a service callback also
15112            // counts as being in the foreground.
15113            adj = ProcessList.FOREGROUND_APP_ADJ;
15114            schedGroup = app.execServicesFg ?
15115                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15116            app.adjType = "exec-service";
15117            procState = ActivityManager.PROCESS_STATE_SERVICE;
15118            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15119        } else {
15120            // As far as we know the process is empty.  We may change our mind later.
15121            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15122            // At this point we don't actually know the adjustment.  Use the cached adj
15123            // value that the caller wants us to.
15124            adj = cachedAdj;
15125            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15126            app.cached = true;
15127            app.empty = true;
15128            app.adjType = "cch-empty";
15129        }
15130
15131        // Examine all activities if not already foreground.
15132        if (!foregroundActivities && activitiesSize > 0) {
15133            for (int j = 0; j < activitiesSize; j++) {
15134                final ActivityRecord r = app.activities.get(j);
15135                if (r.app != app) {
15136                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15137                            + app + "?!?");
15138                    continue;
15139                }
15140                if (r.visible) {
15141                    // App has a visible activity; only upgrade adjustment.
15142                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15143                        adj = ProcessList.VISIBLE_APP_ADJ;
15144                        app.adjType = "visible";
15145                    }
15146                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15147                        procState = ActivityManager.PROCESS_STATE_TOP;
15148                    }
15149                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15150                    app.cached = false;
15151                    app.empty = false;
15152                    foregroundActivities = true;
15153                    break;
15154                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15155                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15156                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15157                        app.adjType = "pausing";
15158                    }
15159                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15160                        procState = ActivityManager.PROCESS_STATE_TOP;
15161                    }
15162                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15163                    app.cached = false;
15164                    app.empty = false;
15165                    foregroundActivities = true;
15166                } else if (r.state == ActivityState.STOPPING) {
15167                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15168                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15169                        app.adjType = "stopping";
15170                    }
15171                    // For the process state, we will at this point consider the
15172                    // process to be cached.  It will be cached either as an activity
15173                    // or empty depending on whether the activity is finishing.  We do
15174                    // this so that we can treat the process as cached for purposes of
15175                    // memory trimming (determing current memory level, trim command to
15176                    // send to process) since there can be an arbitrary number of stopping
15177                    // processes and they should soon all go into the cached state.
15178                    if (!r.finishing) {
15179                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15180                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15181                        }
15182                    }
15183                    app.cached = false;
15184                    app.empty = false;
15185                    foregroundActivities = true;
15186                } else {
15187                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15188                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15189                        app.adjType = "cch-act";
15190                    }
15191                }
15192            }
15193        }
15194
15195        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15196            if (app.foregroundServices) {
15197                // The user is aware of this app, so make it visible.
15198                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15199                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15200                app.cached = false;
15201                app.adjType = "fg-service";
15202                schedGroup = Process.THREAD_GROUP_DEFAULT;
15203            } else if (app.forcingToForeground != null) {
15204                // The user is aware of this app, so make it visible.
15205                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15206                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15207                app.cached = false;
15208                app.adjType = "force-fg";
15209                app.adjSource = app.forcingToForeground;
15210                schedGroup = Process.THREAD_GROUP_DEFAULT;
15211            }
15212        }
15213
15214        if (app == mHeavyWeightProcess) {
15215            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15216                // We don't want to kill the current heavy-weight process.
15217                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15218                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15219                app.cached = false;
15220                app.adjType = "heavy";
15221            }
15222            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15223                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15224            }
15225        }
15226
15227        if (app == mHomeProcess) {
15228            if (adj > ProcessList.HOME_APP_ADJ) {
15229                // This process is hosting what we currently consider to be the
15230                // home app, so we don't want to let it go into the background.
15231                adj = ProcessList.HOME_APP_ADJ;
15232                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15233                app.cached = false;
15234                app.adjType = "home";
15235            }
15236            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15237                procState = ActivityManager.PROCESS_STATE_HOME;
15238            }
15239        }
15240
15241        if (app == mPreviousProcess && app.activities.size() > 0) {
15242            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15243                // This was the previous process that showed UI to the user.
15244                // We want to try to keep it around more aggressively, to give
15245                // a good experience around switching between two apps.
15246                adj = ProcessList.PREVIOUS_APP_ADJ;
15247                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15248                app.cached = false;
15249                app.adjType = "previous";
15250            }
15251            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15252                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15253            }
15254        }
15255
15256        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15257                + " reason=" + app.adjType);
15258
15259        // By default, we use the computed adjustment.  It may be changed if
15260        // there are applications dependent on our services or providers, but
15261        // this gives us a baseline and makes sure we don't get into an
15262        // infinite recursion.
15263        app.adjSeq = mAdjSeq;
15264        app.curRawAdj = adj;
15265        app.hasStartedServices = false;
15266
15267        if (mBackupTarget != null && app == mBackupTarget.app) {
15268            // If possible we want to avoid killing apps while they're being backed up
15269            if (adj > ProcessList.BACKUP_APP_ADJ) {
15270                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15271                adj = ProcessList.BACKUP_APP_ADJ;
15272                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15273                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15274                }
15275                app.adjType = "backup";
15276                app.cached = false;
15277            }
15278            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15279                procState = ActivityManager.PROCESS_STATE_BACKUP;
15280            }
15281        }
15282
15283        boolean mayBeTop = false;
15284
15285        for (int is = app.services.size()-1;
15286                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15287                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15288                        || procState > ActivityManager.PROCESS_STATE_TOP);
15289                is--) {
15290            ServiceRecord s = app.services.valueAt(is);
15291            if (s.startRequested) {
15292                app.hasStartedServices = true;
15293                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15294                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15295                }
15296                if (app.hasShownUi && app != mHomeProcess) {
15297                    // If this process has shown some UI, let it immediately
15298                    // go to the LRU list because it may be pretty heavy with
15299                    // UI stuff.  We'll tag it with a label just to help
15300                    // debug and understand what is going on.
15301                    if (adj > ProcessList.SERVICE_ADJ) {
15302                        app.adjType = "cch-started-ui-services";
15303                    }
15304                } else {
15305                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15306                        // This service has seen some activity within
15307                        // recent memory, so we will keep its process ahead
15308                        // of the background processes.
15309                        if (adj > ProcessList.SERVICE_ADJ) {
15310                            adj = ProcessList.SERVICE_ADJ;
15311                            app.adjType = "started-services";
15312                            app.cached = false;
15313                        }
15314                    }
15315                    // If we have let the service slide into the background
15316                    // state, still have some text describing what it is doing
15317                    // even though the service no longer has an impact.
15318                    if (adj > ProcessList.SERVICE_ADJ) {
15319                        app.adjType = "cch-started-services";
15320                    }
15321                }
15322                // Don't kill this process because it is doing work; it
15323                // has said it is doing work.
15324                app.keeping = true;
15325            }
15326            for (int conni = s.connections.size()-1;
15327                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15328                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15329                            || procState > ActivityManager.PROCESS_STATE_TOP);
15330                    conni--) {
15331                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15332                for (int i = 0;
15333                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15334                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15335                                || procState > ActivityManager.PROCESS_STATE_TOP);
15336                        i++) {
15337                    // XXX should compute this based on the max of
15338                    // all connected clients.
15339                    ConnectionRecord cr = clist.get(i);
15340                    if (cr.binding.client == app) {
15341                        // Binding to ourself is not interesting.
15342                        continue;
15343                    }
15344                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15345                        ProcessRecord client = cr.binding.client;
15346                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15347                                TOP_APP, doingAll, now);
15348                        int clientProcState = client.curProcState;
15349                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15350                            // If the other app is cached for any reason, for purposes here
15351                            // we are going to consider it empty.  The specific cached state
15352                            // doesn't propagate except under certain conditions.
15353                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15354                        }
15355                        String adjType = null;
15356                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15357                            // Not doing bind OOM management, so treat
15358                            // this guy more like a started service.
15359                            if (app.hasShownUi && app != mHomeProcess) {
15360                                // If this process has shown some UI, let it immediately
15361                                // go to the LRU list because it may be pretty heavy with
15362                                // UI stuff.  We'll tag it with a label just to help
15363                                // debug and understand what is going on.
15364                                if (adj > clientAdj) {
15365                                    adjType = "cch-bound-ui-services";
15366                                }
15367                                app.cached = false;
15368                                clientAdj = adj;
15369                                clientProcState = procState;
15370                            } else {
15371                                if (now >= (s.lastActivity
15372                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15373                                    // This service has not seen activity within
15374                                    // recent memory, so allow it to drop to the
15375                                    // LRU list if there is no other reason to keep
15376                                    // it around.  We'll also tag it with a label just
15377                                    // to help debug and undertand what is going on.
15378                                    if (adj > clientAdj) {
15379                                        adjType = "cch-bound-services";
15380                                    }
15381                                    clientAdj = adj;
15382                                }
15383                            }
15384                        }
15385                        if (adj > clientAdj) {
15386                            // If this process has recently shown UI, and
15387                            // the process that is binding to it is less
15388                            // important than being visible, then we don't
15389                            // care about the binding as much as we care
15390                            // about letting this process get into the LRU
15391                            // list to be killed and restarted if needed for
15392                            // memory.
15393                            if (app.hasShownUi && app != mHomeProcess
15394                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15395                                adjType = "cch-bound-ui-services";
15396                            } else {
15397                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15398                                        |Context.BIND_IMPORTANT)) != 0) {
15399                                    adj = clientAdj;
15400                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15401                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15402                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15403                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15404                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15405                                    adj = clientAdj;
15406                                } else {
15407                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15408                                        adj = ProcessList.VISIBLE_APP_ADJ;
15409                                    }
15410                                }
15411                                if (!client.cached) {
15412                                    app.cached = false;
15413                                }
15414                                if (client.keeping) {
15415                                    app.keeping = true;
15416                                }
15417                                adjType = "service";
15418                            }
15419                        }
15420                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15421                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15422                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15423                            }
15424                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15425                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15426                                    // Special handling of clients who are in the top state.
15427                                    // We *may* want to consider this process to be in the
15428                                    // top state as well, but only if there is not another
15429                                    // reason for it to be running.  Being on the top is a
15430                                    // special state, meaning you are specifically running
15431                                    // for the current top app.  If the process is already
15432                                    // running in the background for some other reason, it
15433                                    // is more important to continue considering it to be
15434                                    // in the background state.
15435                                    mayBeTop = true;
15436                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15437                                } else {
15438                                    // Special handling for above-top states (persistent
15439                                    // processes).  These should not bring the current process
15440                                    // into the top state, since they are not on top.  Instead
15441                                    // give them the best state after that.
15442                                    clientProcState =
15443                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15444                                }
15445                            }
15446                        } else {
15447                            if (clientProcState <
15448                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15449                                clientProcState =
15450                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15451                            }
15452                        }
15453                        if (procState > clientProcState) {
15454                            procState = clientProcState;
15455                        }
15456                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15457                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15458                            app.pendingUiClean = true;
15459                        }
15460                        if (adjType != null) {
15461                            app.adjType = adjType;
15462                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15463                                    .REASON_SERVICE_IN_USE;
15464                            app.adjSource = cr.binding.client;
15465                            app.adjSourceOom = clientAdj;
15466                            app.adjTarget = s.name;
15467                        }
15468                    }
15469                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15470                        app.treatLikeActivity = true;
15471                    }
15472                    final ActivityRecord a = cr.activity;
15473                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15474                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15475                                (a.visible || a.state == ActivityState.RESUMED
15476                                 || a.state == ActivityState.PAUSING)) {
15477                            adj = ProcessList.FOREGROUND_APP_ADJ;
15478                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15479                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15480                            }
15481                            app.cached = false;
15482                            app.adjType = "service";
15483                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15484                                    .REASON_SERVICE_IN_USE;
15485                            app.adjSource = a;
15486                            app.adjSourceOom = adj;
15487                            app.adjTarget = s.name;
15488                        }
15489                    }
15490                }
15491            }
15492        }
15493
15494        for (int provi = app.pubProviders.size()-1;
15495                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15496                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15497                        || procState > ActivityManager.PROCESS_STATE_TOP);
15498                provi--) {
15499            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15500            for (int i = cpr.connections.size()-1;
15501                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15502                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15503                            || procState > ActivityManager.PROCESS_STATE_TOP);
15504                    i--) {
15505                ContentProviderConnection conn = cpr.connections.get(i);
15506                ProcessRecord client = conn.client;
15507                if (client == app) {
15508                    // Being our own client is not interesting.
15509                    continue;
15510                }
15511                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15512                int clientProcState = client.curProcState;
15513                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15514                    // If the other app is cached for any reason, for purposes here
15515                    // we are going to consider it empty.
15516                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15517                }
15518                if (adj > clientAdj) {
15519                    if (app.hasShownUi && app != mHomeProcess
15520                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15521                        app.adjType = "cch-ui-provider";
15522                    } else {
15523                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15524                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15525                        app.adjType = "provider";
15526                    }
15527                    app.cached &= client.cached;
15528                    app.keeping |= client.keeping;
15529                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15530                            .REASON_PROVIDER_IN_USE;
15531                    app.adjSource = client;
15532                    app.adjSourceOom = clientAdj;
15533                    app.adjTarget = cpr.name;
15534                }
15535                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15536                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15537                        // Special handling of clients who are in the top state.
15538                        // We *may* want to consider this process to be in the
15539                        // top state as well, but only if there is not another
15540                        // reason for it to be running.  Being on the top is a
15541                        // special state, meaning you are specifically running
15542                        // for the current top app.  If the process is already
15543                        // running in the background for some other reason, it
15544                        // is more important to continue considering it to be
15545                        // in the background state.
15546                        mayBeTop = true;
15547                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15548                    } else {
15549                        // Special handling for above-top states (persistent
15550                        // processes).  These should not bring the current process
15551                        // into the top state, since they are not on top.  Instead
15552                        // give them the best state after that.
15553                        clientProcState =
15554                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15555                    }
15556                }
15557                if (procState > clientProcState) {
15558                    procState = clientProcState;
15559                }
15560                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15561                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15562                }
15563            }
15564            // If the provider has external (non-framework) process
15565            // dependencies, ensure that its adjustment is at least
15566            // FOREGROUND_APP_ADJ.
15567            if (cpr.hasExternalProcessHandles()) {
15568                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15569                    adj = ProcessList.FOREGROUND_APP_ADJ;
15570                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15571                    app.cached = false;
15572                    app.keeping = true;
15573                    app.adjType = "provider";
15574                    app.adjTarget = cpr.name;
15575                }
15576                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15577                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15578                }
15579            }
15580        }
15581
15582        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15583            // A client of one of our services or providers is in the top state.  We
15584            // *may* want to be in the top state, but not if we are already running in
15585            // the background for some other reason.  For the decision here, we are going
15586            // to pick out a few specific states that we want to remain in when a client
15587            // is top (states that tend to be longer-term) and otherwise allow it to go
15588            // to the top state.
15589            switch (procState) {
15590                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15591                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15592                case ActivityManager.PROCESS_STATE_SERVICE:
15593                    // These all are longer-term states, so pull them up to the top
15594                    // of the background states, but not all the way to the top state.
15595                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15596                    break;
15597                default:
15598                    // Otherwise, top is a better choice, so take it.
15599                    procState = ActivityManager.PROCESS_STATE_TOP;
15600                    break;
15601            }
15602        }
15603
15604        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15605            if (app.hasClientActivities) {
15606                // This is a cached process, but with client activities.  Mark it so.
15607                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15608                app.adjType = "cch-client-act";
15609            } else if (app.treatLikeActivity) {
15610                // This is a cached process, but somebody wants us to treat it like it has
15611                // an activity, okay!
15612                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15613                app.adjType = "cch-as-act";
15614            }
15615        }
15616
15617        if (adj == ProcessList.SERVICE_ADJ) {
15618            if (doingAll) {
15619                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15620                mNewNumServiceProcs++;
15621                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15622                if (!app.serviceb) {
15623                    // This service isn't far enough down on the LRU list to
15624                    // normally be a B service, but if we are low on RAM and it
15625                    // is large we want to force it down since we would prefer to
15626                    // keep launcher over it.
15627                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15628                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15629                        app.serviceHighRam = true;
15630                        app.serviceb = true;
15631                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15632                    } else {
15633                        mNewNumAServiceProcs++;
15634                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15635                    }
15636                } else {
15637                    app.serviceHighRam = false;
15638                }
15639            }
15640            if (app.serviceb) {
15641                adj = ProcessList.SERVICE_B_ADJ;
15642            }
15643        }
15644
15645        app.curRawAdj = adj;
15646
15647        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15648        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15649        if (adj > app.maxAdj) {
15650            adj = app.maxAdj;
15651            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15652                schedGroup = Process.THREAD_GROUP_DEFAULT;
15653            }
15654        }
15655        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15656            app.keeping = true;
15657        }
15658
15659        // Do final modification to adj.  Everything we do between here and applying
15660        // the final setAdj must be done in this function, because we will also use
15661        // it when computing the final cached adj later.  Note that we don't need to
15662        // worry about this for max adj above, since max adj will always be used to
15663        // keep it out of the cached vaues.
15664        app.curAdj = app.modifyRawOomAdj(adj);
15665        app.curSchedGroup = schedGroup;
15666        app.curProcState = procState;
15667        app.foregroundActivities = foregroundActivities;
15668
15669        return app.curRawAdj;
15670    }
15671
15672    /**
15673     * Schedule PSS collection of a process.
15674     */
15675    void requestPssLocked(ProcessRecord proc, int procState) {
15676        if (mPendingPssProcesses.contains(proc)) {
15677            return;
15678        }
15679        if (mPendingPssProcesses.size() == 0) {
15680            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15681        }
15682        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15683        proc.pssProcState = procState;
15684        mPendingPssProcesses.add(proc);
15685    }
15686
15687    /**
15688     * Schedule PSS collection of all processes.
15689     */
15690    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15691        if (!always) {
15692            if (now < (mLastFullPssTime +
15693                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15694                return;
15695            }
15696        }
15697        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15698        mLastFullPssTime = now;
15699        mFullPssPending = true;
15700        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15701        mPendingPssProcesses.clear();
15702        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15703            ProcessRecord app = mLruProcesses.get(i);
15704            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15705                app.pssProcState = app.setProcState;
15706                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15707                        isSleeping(), now);
15708                mPendingPssProcesses.add(app);
15709            }
15710        }
15711        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15712    }
15713
15714    /**
15715     * Ask a given process to GC right now.
15716     */
15717    final void performAppGcLocked(ProcessRecord app) {
15718        try {
15719            app.lastRequestedGc = SystemClock.uptimeMillis();
15720            if (app.thread != null) {
15721                if (app.reportLowMemory) {
15722                    app.reportLowMemory = false;
15723                    app.thread.scheduleLowMemory();
15724                } else {
15725                    app.thread.processInBackground();
15726                }
15727            }
15728        } catch (Exception e) {
15729            // whatever.
15730        }
15731    }
15732
15733    /**
15734     * Returns true if things are idle enough to perform GCs.
15735     */
15736    private final boolean canGcNowLocked() {
15737        boolean processingBroadcasts = false;
15738        for (BroadcastQueue q : mBroadcastQueues) {
15739            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15740                processingBroadcasts = true;
15741            }
15742        }
15743        return !processingBroadcasts
15744                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15745    }
15746
15747    /**
15748     * Perform GCs on all processes that are waiting for it, but only
15749     * if things are idle.
15750     */
15751    final void performAppGcsLocked() {
15752        final int N = mProcessesToGc.size();
15753        if (N <= 0) {
15754            return;
15755        }
15756        if (canGcNowLocked()) {
15757            while (mProcessesToGc.size() > 0) {
15758                ProcessRecord proc = mProcessesToGc.remove(0);
15759                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15760                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15761                            <= SystemClock.uptimeMillis()) {
15762                        // To avoid spamming the system, we will GC processes one
15763                        // at a time, waiting a few seconds between each.
15764                        performAppGcLocked(proc);
15765                        scheduleAppGcsLocked();
15766                        return;
15767                    } else {
15768                        // It hasn't been long enough since we last GCed this
15769                        // process...  put it in the list to wait for its time.
15770                        addProcessToGcListLocked(proc);
15771                        break;
15772                    }
15773                }
15774            }
15775
15776            scheduleAppGcsLocked();
15777        }
15778    }
15779
15780    /**
15781     * If all looks good, perform GCs on all processes waiting for them.
15782     */
15783    final void performAppGcsIfAppropriateLocked() {
15784        if (canGcNowLocked()) {
15785            performAppGcsLocked();
15786            return;
15787        }
15788        // Still not idle, wait some more.
15789        scheduleAppGcsLocked();
15790    }
15791
15792    /**
15793     * Schedule the execution of all pending app GCs.
15794     */
15795    final void scheduleAppGcsLocked() {
15796        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15797
15798        if (mProcessesToGc.size() > 0) {
15799            // Schedule a GC for the time to the next process.
15800            ProcessRecord proc = mProcessesToGc.get(0);
15801            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15802
15803            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15804            long now = SystemClock.uptimeMillis();
15805            if (when < (now+GC_TIMEOUT)) {
15806                when = now + GC_TIMEOUT;
15807            }
15808            mHandler.sendMessageAtTime(msg, when);
15809        }
15810    }
15811
15812    /**
15813     * Add a process to the array of processes waiting to be GCed.  Keeps the
15814     * list in sorted order by the last GC time.  The process can't already be
15815     * on the list.
15816     */
15817    final void addProcessToGcListLocked(ProcessRecord proc) {
15818        boolean added = false;
15819        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15820            if (mProcessesToGc.get(i).lastRequestedGc <
15821                    proc.lastRequestedGc) {
15822                added = true;
15823                mProcessesToGc.add(i+1, proc);
15824                break;
15825            }
15826        }
15827        if (!added) {
15828            mProcessesToGc.add(0, proc);
15829        }
15830    }
15831
15832    /**
15833     * Set up to ask a process to GC itself.  This will either do it
15834     * immediately, or put it on the list of processes to gc the next
15835     * time things are idle.
15836     */
15837    final void scheduleAppGcLocked(ProcessRecord app) {
15838        long now = SystemClock.uptimeMillis();
15839        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15840            return;
15841        }
15842        if (!mProcessesToGc.contains(app)) {
15843            addProcessToGcListLocked(app);
15844            scheduleAppGcsLocked();
15845        }
15846    }
15847
15848    final void checkExcessivePowerUsageLocked(boolean doKills) {
15849        updateCpuStatsNow();
15850
15851        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15852        boolean doWakeKills = doKills;
15853        boolean doCpuKills = doKills;
15854        if (mLastPowerCheckRealtime == 0) {
15855            doWakeKills = false;
15856        }
15857        if (mLastPowerCheckUptime == 0) {
15858            doCpuKills = false;
15859        }
15860        if (stats.isScreenOn()) {
15861            doWakeKills = false;
15862        }
15863        final long curRealtime = SystemClock.elapsedRealtime();
15864        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15865        final long curUptime = SystemClock.uptimeMillis();
15866        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15867        mLastPowerCheckRealtime = curRealtime;
15868        mLastPowerCheckUptime = curUptime;
15869        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15870            doWakeKills = false;
15871        }
15872        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15873            doCpuKills = false;
15874        }
15875        int i = mLruProcesses.size();
15876        while (i > 0) {
15877            i--;
15878            ProcessRecord app = mLruProcesses.get(i);
15879            if (!app.keeping) {
15880                long wtime;
15881                synchronized (stats) {
15882                    wtime = stats.getProcessWakeTime(app.info.uid,
15883                            app.pid, curRealtime);
15884                }
15885                long wtimeUsed = wtime - app.lastWakeTime;
15886                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15887                if (DEBUG_POWER) {
15888                    StringBuilder sb = new StringBuilder(128);
15889                    sb.append("Wake for ");
15890                    app.toShortString(sb);
15891                    sb.append(": over ");
15892                    TimeUtils.formatDuration(realtimeSince, sb);
15893                    sb.append(" used ");
15894                    TimeUtils.formatDuration(wtimeUsed, sb);
15895                    sb.append(" (");
15896                    sb.append((wtimeUsed*100)/realtimeSince);
15897                    sb.append("%)");
15898                    Slog.i(TAG, sb.toString());
15899                    sb.setLength(0);
15900                    sb.append("CPU for ");
15901                    app.toShortString(sb);
15902                    sb.append(": over ");
15903                    TimeUtils.formatDuration(uptimeSince, sb);
15904                    sb.append(" used ");
15905                    TimeUtils.formatDuration(cputimeUsed, sb);
15906                    sb.append(" (");
15907                    sb.append((cputimeUsed*100)/uptimeSince);
15908                    sb.append("%)");
15909                    Slog.i(TAG, sb.toString());
15910                }
15911                // If a process has held a wake lock for more
15912                // than 50% of the time during this period,
15913                // that sounds bad.  Kill!
15914                if (doWakeKills && realtimeSince > 0
15915                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15916                    synchronized (stats) {
15917                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15918                                realtimeSince, wtimeUsed);
15919                    }
15920                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15921                            + " during " + realtimeSince);
15922                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15923                } else if (doCpuKills && uptimeSince > 0
15924                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15925                    synchronized (stats) {
15926                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15927                                uptimeSince, cputimeUsed);
15928                    }
15929                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15930                            + " during " + uptimeSince);
15931                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15932                } else {
15933                    app.lastWakeTime = wtime;
15934                    app.lastCpuTime = app.curCpuTime;
15935                }
15936            }
15937        }
15938    }
15939
15940    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15941            ProcessRecord TOP_APP, boolean doingAll, long now) {
15942        boolean success = true;
15943
15944        if (app.curRawAdj != app.setRawAdj) {
15945            if (wasKeeping && !app.keeping) {
15946                // This app is no longer something we want to keep.  Note
15947                // its current wake lock time to later know to kill it if
15948                // it is not behaving well.
15949                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15950                synchronized (stats) {
15951                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15952                            app.pid, SystemClock.elapsedRealtime());
15953                }
15954                app.lastCpuTime = app.curCpuTime;
15955            }
15956
15957            app.setRawAdj = app.curRawAdj;
15958        }
15959
15960        int changes = 0;
15961
15962        if (app.curAdj != app.setAdj) {
15963            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
15964            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15965                TAG, "Set " + app.pid + " " + app.processName +
15966                " adj " + app.curAdj + ": " + app.adjType);
15967            app.setAdj = app.curAdj;
15968        }
15969
15970        if (app.setSchedGroup != app.curSchedGroup) {
15971            app.setSchedGroup = app.curSchedGroup;
15972            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15973                    "Setting process group of " + app.processName
15974                    + " to " + app.curSchedGroup);
15975            if (app.waitingToKill != null &&
15976                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15977                killUnneededProcessLocked(app, app.waitingToKill);
15978                success = false;
15979            } else {
15980                if (true) {
15981                    long oldId = Binder.clearCallingIdentity();
15982                    try {
15983                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15984                    } catch (Exception e) {
15985                        Slog.w(TAG, "Failed setting process group of " + app.pid
15986                                + " to " + app.curSchedGroup);
15987                        e.printStackTrace();
15988                    } finally {
15989                        Binder.restoreCallingIdentity(oldId);
15990                    }
15991                } else {
15992                    if (app.thread != null) {
15993                        try {
15994                            app.thread.setSchedulingGroup(app.curSchedGroup);
15995                        } catch (RemoteException e) {
15996                        }
15997                    }
15998                }
15999                Process.setSwappiness(app.pid,
16000                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16001            }
16002        }
16003        if (app.repForegroundActivities != app.foregroundActivities) {
16004            app.repForegroundActivities = app.foregroundActivities;
16005            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16006        }
16007        if (app.repProcState != app.curProcState) {
16008            app.repProcState = app.curProcState;
16009            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16010            if (app.thread != null) {
16011                try {
16012                    if (false) {
16013                        //RuntimeException h = new RuntimeException("here");
16014                        Slog.i(TAG, "Sending new process state " + app.repProcState
16015                                + " to " + app /*, h*/);
16016                    }
16017                    app.thread.setProcessState(app.repProcState);
16018                } catch (RemoteException e) {
16019                }
16020            }
16021        }
16022        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16023                app.setProcState)) {
16024            app.lastStateTime = now;
16025            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16026                    isSleeping(), now);
16027            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16028                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16029                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16030                    + (app.nextPssTime-now) + ": " + app);
16031        } else {
16032            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16033                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16034                requestPssLocked(app, app.setProcState);
16035                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16036                        isSleeping(), now);
16037            } else if (false && DEBUG_PSS) {
16038                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16039            }
16040        }
16041        if (app.setProcState != app.curProcState) {
16042            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16043                    "Proc state change of " + app.processName
16044                    + " to " + app.curProcState);
16045            app.setProcState = app.curProcState;
16046            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16047                app.notCachedSinceIdle = false;
16048            }
16049            if (!doingAll) {
16050                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16051            } else {
16052                app.procStateChanged = true;
16053            }
16054        }
16055
16056        if (changes != 0) {
16057            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16058            int i = mPendingProcessChanges.size()-1;
16059            ProcessChangeItem item = null;
16060            while (i >= 0) {
16061                item = mPendingProcessChanges.get(i);
16062                if (item.pid == app.pid) {
16063                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16064                    break;
16065                }
16066                i--;
16067            }
16068            if (i < 0) {
16069                // No existing item in pending changes; need a new one.
16070                final int NA = mAvailProcessChanges.size();
16071                if (NA > 0) {
16072                    item = mAvailProcessChanges.remove(NA-1);
16073                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16074                } else {
16075                    item = new ProcessChangeItem();
16076                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16077                }
16078                item.changes = 0;
16079                item.pid = app.pid;
16080                item.uid = app.info.uid;
16081                if (mPendingProcessChanges.size() == 0) {
16082                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16083                            "*** Enqueueing dispatch processes changed!");
16084                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16085                }
16086                mPendingProcessChanges.add(item);
16087            }
16088            item.changes |= changes;
16089            item.processState = app.repProcState;
16090            item.foregroundActivities = app.repForegroundActivities;
16091            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16092                    + Integer.toHexString(System.identityHashCode(item))
16093                    + " " + app.toShortString() + ": changes=" + item.changes
16094                    + " procState=" + item.processState
16095                    + " foreground=" + item.foregroundActivities
16096                    + " type=" + app.adjType + " source=" + app.adjSource
16097                    + " target=" + app.adjTarget);
16098        }
16099
16100        return success;
16101    }
16102
16103    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16104        if (proc.thread != null) {
16105            if (proc.baseProcessTracker != null) {
16106                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16107            }
16108            if (proc.repProcState >= 0) {
16109                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16110                        proc.repProcState);
16111            }
16112        }
16113    }
16114
16115    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16116            ProcessRecord TOP_APP, boolean doingAll, long now) {
16117        if (app.thread == null) {
16118            return false;
16119        }
16120
16121        final boolean wasKeeping = app.keeping;
16122
16123        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16124
16125        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16126    }
16127
16128    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16129            boolean oomAdj) {
16130        if (isForeground != proc.foregroundServices) {
16131            proc.foregroundServices = isForeground;
16132            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16133                    proc.info.uid);
16134            if (isForeground) {
16135                if (curProcs == null) {
16136                    curProcs = new ArrayList<ProcessRecord>();
16137                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16138                }
16139                if (!curProcs.contains(proc)) {
16140                    curProcs.add(proc);
16141                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16142                            proc.info.packageName, proc.info.uid);
16143                }
16144            } else {
16145                if (curProcs != null) {
16146                    if (curProcs.remove(proc)) {
16147                        mBatteryStatsService.noteEvent(
16148                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16149                                proc.info.packageName, proc.info.uid);
16150                        if (curProcs.size() <= 0) {
16151                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16152                        }
16153                    }
16154                }
16155            }
16156            if (oomAdj) {
16157                updateOomAdjLocked();
16158            }
16159        }
16160    }
16161
16162    private final ActivityRecord resumedAppLocked() {
16163        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16164        String pkg;
16165        int uid;
16166        if (act != null) {
16167            pkg = act.packageName;
16168            uid = act.info.applicationInfo.uid;
16169        } else {
16170            pkg = null;
16171            uid = -1;
16172        }
16173        // Has the UID or resumed package name changed?
16174        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16175                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16176            if (mCurResumedPackage != null) {
16177                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16178                        mCurResumedPackage, mCurResumedUid);
16179            }
16180            mCurResumedPackage = pkg;
16181            mCurResumedUid = uid;
16182            if (mCurResumedPackage != null) {
16183                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16184                        mCurResumedPackage, mCurResumedUid);
16185            }
16186        }
16187        return act;
16188    }
16189
16190    final boolean updateOomAdjLocked(ProcessRecord app) {
16191        final ActivityRecord TOP_ACT = resumedAppLocked();
16192        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16193        final boolean wasCached = app.cached;
16194
16195        mAdjSeq++;
16196
16197        // This is the desired cached adjusment we want to tell it to use.
16198        // If our app is currently cached, we know it, and that is it.  Otherwise,
16199        // we don't know it yet, and it needs to now be cached we will then
16200        // need to do a complete oom adj.
16201        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16202                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16203        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16204                SystemClock.uptimeMillis());
16205        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16206            // Changed to/from cached state, so apps after it in the LRU
16207            // list may also be changed.
16208            updateOomAdjLocked();
16209        }
16210        return success;
16211    }
16212
16213    final void updateOomAdjLocked() {
16214        final ActivityRecord TOP_ACT = resumedAppLocked();
16215        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16216        final long now = SystemClock.uptimeMillis();
16217        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16218        final int N = mLruProcesses.size();
16219
16220        if (false) {
16221            RuntimeException e = new RuntimeException();
16222            e.fillInStackTrace();
16223            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16224        }
16225
16226        mAdjSeq++;
16227        mNewNumServiceProcs = 0;
16228        mNewNumAServiceProcs = 0;
16229
16230        final int emptyProcessLimit;
16231        final int cachedProcessLimit;
16232        if (mProcessLimit <= 0) {
16233            emptyProcessLimit = cachedProcessLimit = 0;
16234        } else if (mProcessLimit == 1) {
16235            emptyProcessLimit = 1;
16236            cachedProcessLimit = 0;
16237        } else {
16238            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16239            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16240        }
16241
16242        // Let's determine how many processes we have running vs.
16243        // how many slots we have for background processes; we may want
16244        // to put multiple processes in a slot of there are enough of
16245        // them.
16246        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16247                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16248        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16249        if (numEmptyProcs > cachedProcessLimit) {
16250            // If there are more empty processes than our limit on cached
16251            // processes, then use the cached process limit for the factor.
16252            // This ensures that the really old empty processes get pushed
16253            // down to the bottom, so if we are running low on memory we will
16254            // have a better chance at keeping around more cached processes
16255            // instead of a gazillion empty processes.
16256            numEmptyProcs = cachedProcessLimit;
16257        }
16258        int emptyFactor = numEmptyProcs/numSlots;
16259        if (emptyFactor < 1) emptyFactor = 1;
16260        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16261        if (cachedFactor < 1) cachedFactor = 1;
16262        int stepCached = 0;
16263        int stepEmpty = 0;
16264        int numCached = 0;
16265        int numEmpty = 0;
16266        int numTrimming = 0;
16267
16268        mNumNonCachedProcs = 0;
16269        mNumCachedHiddenProcs = 0;
16270
16271        // First update the OOM adjustment for each of the
16272        // application processes based on their current state.
16273        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16274        int nextCachedAdj = curCachedAdj+1;
16275        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16276        int nextEmptyAdj = curEmptyAdj+2;
16277        for (int i=N-1; i>=0; i--) {
16278            ProcessRecord app = mLruProcesses.get(i);
16279            if (!app.killedByAm && app.thread != null) {
16280                app.procStateChanged = false;
16281                final boolean wasKeeping = app.keeping;
16282                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16283
16284                // If we haven't yet assigned the final cached adj
16285                // to the process, do that now.
16286                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16287                    switch (app.curProcState) {
16288                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16289                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16290                            // This process is a cached process holding activities...
16291                            // assign it the next cached value for that type, and then
16292                            // step that cached level.
16293                            app.curRawAdj = curCachedAdj;
16294                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16295                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16296                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16297                                    + ")");
16298                            if (curCachedAdj != nextCachedAdj) {
16299                                stepCached++;
16300                                if (stepCached >= cachedFactor) {
16301                                    stepCached = 0;
16302                                    curCachedAdj = nextCachedAdj;
16303                                    nextCachedAdj += 2;
16304                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16305                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16306                                    }
16307                                }
16308                            }
16309                            break;
16310                        default:
16311                            // For everything else, assign next empty cached process
16312                            // level and bump that up.  Note that this means that
16313                            // long-running services that have dropped down to the
16314                            // cached level will be treated as empty (since their process
16315                            // state is still as a service), which is what we want.
16316                            app.curRawAdj = curEmptyAdj;
16317                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16318                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16319                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16320                                    + ")");
16321                            if (curEmptyAdj != nextEmptyAdj) {
16322                                stepEmpty++;
16323                                if (stepEmpty >= emptyFactor) {
16324                                    stepEmpty = 0;
16325                                    curEmptyAdj = nextEmptyAdj;
16326                                    nextEmptyAdj += 2;
16327                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16328                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16329                                    }
16330                                }
16331                            }
16332                            break;
16333                    }
16334                }
16335
16336                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16337
16338                // Count the number of process types.
16339                switch (app.curProcState) {
16340                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16341                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16342                        mNumCachedHiddenProcs++;
16343                        numCached++;
16344                        if (numCached > cachedProcessLimit) {
16345                            killUnneededProcessLocked(app, "cached #" + numCached);
16346                        }
16347                        break;
16348                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16349                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16350                                && app.lastActivityTime < oldTime) {
16351                            killUnneededProcessLocked(app, "empty for "
16352                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16353                                    / 1000) + "s");
16354                        } else {
16355                            numEmpty++;
16356                            if (numEmpty > emptyProcessLimit) {
16357                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16358                            }
16359                        }
16360                        break;
16361                    default:
16362                        mNumNonCachedProcs++;
16363                        break;
16364                }
16365
16366                if (app.isolated && app.services.size() <= 0) {
16367                    // If this is an isolated process, and there are no
16368                    // services running in it, then the process is no longer
16369                    // needed.  We agressively kill these because we can by
16370                    // definition not re-use the same process again, and it is
16371                    // good to avoid having whatever code was running in them
16372                    // left sitting around after no longer needed.
16373                    killUnneededProcessLocked(app, "isolated not needed");
16374                }
16375
16376                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16377                        && !app.killedByAm) {
16378                    numTrimming++;
16379                }
16380            }
16381        }
16382
16383        mNumServiceProcs = mNewNumServiceProcs;
16384
16385        // Now determine the memory trimming level of background processes.
16386        // Unfortunately we need to start at the back of the list to do this
16387        // properly.  We only do this if the number of background apps we
16388        // are managing to keep around is less than half the maximum we desire;
16389        // if we are keeping a good number around, we'll let them use whatever
16390        // memory they want.
16391        final int numCachedAndEmpty = numCached + numEmpty;
16392        int memFactor;
16393        if (numCached <= ProcessList.TRIM_CACHED_APPS
16394                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16395            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16396                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16397            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16398                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16399            } else {
16400                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16401            }
16402        } else {
16403            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16404        }
16405        // We always allow the memory level to go up (better).  We only allow it to go
16406        // down if we are in a state where that is allowed, *and* the total number of processes
16407        // has gone down since last time.
16408        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16409                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16410                + " last=" + mLastNumProcesses);
16411        if (memFactor > mLastMemoryLevel) {
16412            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16413                memFactor = mLastMemoryLevel;
16414                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16415            }
16416        }
16417        mLastMemoryLevel = memFactor;
16418        mLastNumProcesses = mLruProcesses.size();
16419        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16420        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16421        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16422            if (mLowRamStartTime == 0) {
16423                mLowRamStartTime = now;
16424            }
16425            int step = 0;
16426            int fgTrimLevel;
16427            switch (memFactor) {
16428                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16429                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16430                    break;
16431                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16432                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16433                    break;
16434                default:
16435                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16436                    break;
16437            }
16438            int factor = numTrimming/3;
16439            int minFactor = 2;
16440            if (mHomeProcess != null) minFactor++;
16441            if (mPreviousProcess != null) minFactor++;
16442            if (factor < minFactor) factor = minFactor;
16443            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16444            for (int i=N-1; i>=0; i--) {
16445                ProcessRecord app = mLruProcesses.get(i);
16446                if (allChanged || app.procStateChanged) {
16447                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16448                    app.procStateChanged = false;
16449                }
16450                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16451                        && !app.killedByAm) {
16452                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16453                        try {
16454                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16455                                    "Trimming memory of " + app.processName
16456                                    + " to " + curLevel);
16457                            app.thread.scheduleTrimMemory(curLevel);
16458                        } catch (RemoteException e) {
16459                        }
16460                        if (false) {
16461                            // For now we won't do this; our memory trimming seems
16462                            // to be good enough at this point that destroying
16463                            // activities causes more harm than good.
16464                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16465                                    && app != mHomeProcess && app != mPreviousProcess) {
16466                                // Need to do this on its own message because the stack may not
16467                                // be in a consistent state at this point.
16468                                // For these apps we will also finish their activities
16469                                // to help them free memory.
16470                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16471                            }
16472                        }
16473                    }
16474                    app.trimMemoryLevel = curLevel;
16475                    step++;
16476                    if (step >= factor) {
16477                        step = 0;
16478                        switch (curLevel) {
16479                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16480                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16481                                break;
16482                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16483                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16484                                break;
16485                        }
16486                    }
16487                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16488                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16489                            && app.thread != null) {
16490                        try {
16491                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16492                                    "Trimming memory of heavy-weight " + app.processName
16493                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16494                            app.thread.scheduleTrimMemory(
16495                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16496                        } catch (RemoteException e) {
16497                        }
16498                    }
16499                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16500                } else {
16501                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16502                            || app.systemNoUi) && app.pendingUiClean) {
16503                        // If this application is now in the background and it
16504                        // had done UI, then give it the special trim level to
16505                        // have it free UI resources.
16506                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16507                        if (app.trimMemoryLevel < level && app.thread != null) {
16508                            try {
16509                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16510                                        "Trimming memory of bg-ui " + app.processName
16511                                        + " to " + level);
16512                                app.thread.scheduleTrimMemory(level);
16513                            } catch (RemoteException e) {
16514                            }
16515                        }
16516                        app.pendingUiClean = false;
16517                    }
16518                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16519                        try {
16520                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16521                                    "Trimming memory of fg " + app.processName
16522                                    + " to " + fgTrimLevel);
16523                            app.thread.scheduleTrimMemory(fgTrimLevel);
16524                        } catch (RemoteException e) {
16525                        }
16526                    }
16527                    app.trimMemoryLevel = fgTrimLevel;
16528                }
16529            }
16530        } else {
16531            if (mLowRamStartTime != 0) {
16532                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16533                mLowRamStartTime = 0;
16534            }
16535            for (int i=N-1; i>=0; i--) {
16536                ProcessRecord app = mLruProcesses.get(i);
16537                if (allChanged || app.procStateChanged) {
16538                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16539                    app.procStateChanged = false;
16540                }
16541                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16542                        || app.systemNoUi) && app.pendingUiClean) {
16543                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16544                            && app.thread != null) {
16545                        try {
16546                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16547                                    "Trimming memory of ui hidden " + app.processName
16548                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16549                            app.thread.scheduleTrimMemory(
16550                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16551                        } catch (RemoteException e) {
16552                        }
16553                    }
16554                    app.pendingUiClean = false;
16555                }
16556                app.trimMemoryLevel = 0;
16557            }
16558        }
16559
16560        if (mAlwaysFinishActivities) {
16561            // Need to do this on its own message because the stack may not
16562            // be in a consistent state at this point.
16563            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16564        }
16565
16566        if (allChanged) {
16567            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16568        }
16569
16570        if (mProcessStats.shouldWriteNowLocked(now)) {
16571            mHandler.post(new Runnable() {
16572                @Override public void run() {
16573                    synchronized (ActivityManagerService.this) {
16574                        mProcessStats.writeStateAsyncLocked();
16575                    }
16576                }
16577            });
16578        }
16579
16580        if (DEBUG_OOM_ADJ) {
16581            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16582        }
16583    }
16584
16585    final void trimApplications() {
16586        synchronized (this) {
16587            int i;
16588
16589            // First remove any unused application processes whose package
16590            // has been removed.
16591            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16592                final ProcessRecord app = mRemovedProcesses.get(i);
16593                if (app.activities.size() == 0
16594                        && app.curReceiver == null && app.services.size() == 0) {
16595                    Slog.i(
16596                        TAG, "Exiting empty application process "
16597                        + app.processName + " ("
16598                        + (app.thread != null ? app.thread.asBinder() : null)
16599                        + ")\n");
16600                    if (app.pid > 0 && app.pid != MY_PID) {
16601                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16602                                app.processName, app.setAdj, "empty");
16603                        app.killedByAm = true;
16604                        Process.killProcessQuiet(app.pid);
16605                        Process.killProcessGroup(app.info.uid, app.pid);
16606                    } else {
16607                        try {
16608                            app.thread.scheduleExit();
16609                        } catch (Exception e) {
16610                            // Ignore exceptions.
16611                        }
16612                    }
16613                    cleanUpApplicationRecordLocked(app, false, true, -1);
16614                    mRemovedProcesses.remove(i);
16615
16616                    if (app.persistent) {
16617                        addAppLocked(app.info, false, null /* ABI override */);
16618                    }
16619                }
16620            }
16621
16622            // Now update the oom adj for all processes.
16623            updateOomAdjLocked();
16624        }
16625    }
16626
16627    /** This method sends the specified signal to each of the persistent apps */
16628    public void signalPersistentProcesses(int sig) throws RemoteException {
16629        if (sig != Process.SIGNAL_USR1) {
16630            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16631        }
16632
16633        synchronized (this) {
16634            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16635                    != PackageManager.PERMISSION_GRANTED) {
16636                throw new SecurityException("Requires permission "
16637                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16638            }
16639
16640            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16641                ProcessRecord r = mLruProcesses.get(i);
16642                if (r.thread != null && r.persistent) {
16643                    Process.sendSignal(r.pid, sig);
16644                }
16645            }
16646        }
16647    }
16648
16649    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16650        if (proc == null || proc == mProfileProc) {
16651            proc = mProfileProc;
16652            path = mProfileFile;
16653            profileType = mProfileType;
16654            clearProfilerLocked();
16655        }
16656        if (proc == null) {
16657            return;
16658        }
16659        try {
16660            proc.thread.profilerControl(false, path, null, profileType);
16661        } catch (RemoteException e) {
16662            throw new IllegalStateException("Process disappeared");
16663        }
16664    }
16665
16666    private void clearProfilerLocked() {
16667        if (mProfileFd != null) {
16668            try {
16669                mProfileFd.close();
16670            } catch (IOException e) {
16671            }
16672        }
16673        mProfileApp = null;
16674        mProfileProc = null;
16675        mProfileFile = null;
16676        mProfileType = 0;
16677        mAutoStopProfiler = false;
16678    }
16679
16680    public boolean profileControl(String process, int userId, boolean start,
16681            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16682
16683        try {
16684            synchronized (this) {
16685                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16686                // its own permission.
16687                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16688                        != PackageManager.PERMISSION_GRANTED) {
16689                    throw new SecurityException("Requires permission "
16690                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16691                }
16692
16693                if (start && fd == null) {
16694                    throw new IllegalArgumentException("null fd");
16695                }
16696
16697                ProcessRecord proc = null;
16698                if (process != null) {
16699                    proc = findProcessLocked(process, userId, "profileControl");
16700                }
16701
16702                if (start && (proc == null || proc.thread == null)) {
16703                    throw new IllegalArgumentException("Unknown process: " + process);
16704                }
16705
16706                if (start) {
16707                    stopProfilerLocked(null, null, 0);
16708                    setProfileApp(proc.info, proc.processName, path, fd, false);
16709                    mProfileProc = proc;
16710                    mProfileType = profileType;
16711                    try {
16712                        fd = fd.dup();
16713                    } catch (IOException e) {
16714                        fd = null;
16715                    }
16716                    proc.thread.profilerControl(start, path, fd, profileType);
16717                    fd = null;
16718                    mProfileFd = null;
16719                } else {
16720                    stopProfilerLocked(proc, path, profileType);
16721                    if (fd != null) {
16722                        try {
16723                            fd.close();
16724                        } catch (IOException e) {
16725                        }
16726                    }
16727                }
16728
16729                return true;
16730            }
16731        } catch (RemoteException e) {
16732            throw new IllegalStateException("Process disappeared");
16733        } finally {
16734            if (fd != null) {
16735                try {
16736                    fd.close();
16737                } catch (IOException e) {
16738                }
16739            }
16740        }
16741    }
16742
16743    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16744        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16745                userId, true, true, callName, null);
16746        ProcessRecord proc = null;
16747        try {
16748            int pid = Integer.parseInt(process);
16749            synchronized (mPidsSelfLocked) {
16750                proc = mPidsSelfLocked.get(pid);
16751            }
16752        } catch (NumberFormatException e) {
16753        }
16754
16755        if (proc == null) {
16756            ArrayMap<String, SparseArray<ProcessRecord>> all
16757                    = mProcessNames.getMap();
16758            SparseArray<ProcessRecord> procs = all.get(process);
16759            if (procs != null && procs.size() > 0) {
16760                proc = procs.valueAt(0);
16761                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16762                    for (int i=1; i<procs.size(); i++) {
16763                        ProcessRecord thisProc = procs.valueAt(i);
16764                        if (thisProc.userId == userId) {
16765                            proc = thisProc;
16766                            break;
16767                        }
16768                    }
16769                }
16770            }
16771        }
16772
16773        return proc;
16774    }
16775
16776    public boolean dumpHeap(String process, int userId, boolean managed,
16777            String path, ParcelFileDescriptor fd) throws RemoteException {
16778
16779        try {
16780            synchronized (this) {
16781                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16782                // its own permission (same as profileControl).
16783                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16784                        != PackageManager.PERMISSION_GRANTED) {
16785                    throw new SecurityException("Requires permission "
16786                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16787                }
16788
16789                if (fd == null) {
16790                    throw new IllegalArgumentException("null fd");
16791                }
16792
16793                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16794                if (proc == null || proc.thread == null) {
16795                    throw new IllegalArgumentException("Unknown process: " + process);
16796                }
16797
16798                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16799                if (!isDebuggable) {
16800                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16801                        throw new SecurityException("Process not debuggable: " + proc);
16802                    }
16803                }
16804
16805                proc.thread.dumpHeap(managed, path, fd);
16806                fd = null;
16807                return true;
16808            }
16809        } catch (RemoteException e) {
16810            throw new IllegalStateException("Process disappeared");
16811        } finally {
16812            if (fd != null) {
16813                try {
16814                    fd.close();
16815                } catch (IOException e) {
16816                }
16817            }
16818        }
16819    }
16820
16821    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16822    public void monitor() {
16823        synchronized (this) { }
16824    }
16825
16826    void onCoreSettingsChange(Bundle settings) {
16827        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16828            ProcessRecord processRecord = mLruProcesses.get(i);
16829            try {
16830                if (processRecord.thread != null) {
16831                    processRecord.thread.setCoreSettings(settings);
16832                }
16833            } catch (RemoteException re) {
16834                /* ignore */
16835            }
16836        }
16837    }
16838
16839    // Multi-user methods
16840
16841    /**
16842     * Start user, if its not already running, but don't bring it to foreground.
16843     */
16844    @Override
16845    public boolean startUserInBackground(final int userId) {
16846        return startUser(userId, /* foreground */ false);
16847    }
16848
16849    /**
16850     * Refreshes the list of users related to the current user when either a
16851     * user switch happens or when a new related user is started in the
16852     * background.
16853     */
16854    private void updateCurrentProfileIdsLocked() {
16855        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16856                mCurrentUserId, false /* enabledOnly */);
16857        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16858        for (int i = 0; i < currentProfileIds.length; i++) {
16859            currentProfileIds[i] = profiles.get(i).id;
16860        }
16861        mCurrentProfileIds = currentProfileIds;
16862    }
16863
16864    private Set getProfileIdsLocked(int userId) {
16865        Set userIds = new HashSet<Integer>();
16866        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16867                userId, false /* enabledOnly */);
16868        for (UserInfo user : profiles) {
16869            userIds.add(Integer.valueOf(user.id));
16870        }
16871        return userIds;
16872    }
16873
16874    @Override
16875    public boolean switchUser(final int userId) {
16876        return startUser(userId, /* foregound */ true);
16877    }
16878
16879    private boolean startUser(final int userId, boolean foreground) {
16880        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16881                != PackageManager.PERMISSION_GRANTED) {
16882            String msg = "Permission Denial: switchUser() from pid="
16883                    + Binder.getCallingPid()
16884                    + ", uid=" + Binder.getCallingUid()
16885                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16886            Slog.w(TAG, msg);
16887            throw new SecurityException(msg);
16888        }
16889
16890        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16891
16892        final long ident = Binder.clearCallingIdentity();
16893        try {
16894            synchronized (this) {
16895                final int oldUserId = mCurrentUserId;
16896                if (oldUserId == userId) {
16897                    return true;
16898                }
16899
16900                mStackSupervisor.setLockTaskModeLocked(null, false);
16901
16902                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16903                if (userInfo == null) {
16904                    Slog.w(TAG, "No user info for user #" + userId);
16905                    return false;
16906                }
16907
16908                if (foreground) {
16909                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16910                            R.anim.screen_user_enter);
16911                }
16912
16913                boolean needStart = false;
16914
16915                // If the user we are switching to is not currently started, then
16916                // we need to start it now.
16917                if (mStartedUsers.get(userId) == null) {
16918                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16919                    updateStartedUserArrayLocked();
16920                    needStart = true;
16921                }
16922
16923                final Integer userIdInt = Integer.valueOf(userId);
16924                mUserLru.remove(userIdInt);
16925                mUserLru.add(userIdInt);
16926
16927                if (foreground) {
16928                    mCurrentUserId = userId;
16929                    updateCurrentProfileIdsLocked();
16930                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16931                    // Once the internal notion of the active user has switched, we lock the device
16932                    // with the option to show the user switcher on the keyguard.
16933                    mWindowManager.lockNow(null);
16934                } else {
16935                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16936                    updateCurrentProfileIdsLocked();
16937                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16938                    mUserLru.remove(currentUserIdInt);
16939                    mUserLru.add(currentUserIdInt);
16940                }
16941
16942                final UserStartedState uss = mStartedUsers.get(userId);
16943
16944                // Make sure user is in the started state.  If it is currently
16945                // stopping, we need to knock that off.
16946                if (uss.mState == UserStartedState.STATE_STOPPING) {
16947                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16948                    // so we can just fairly silently bring the user back from
16949                    // the almost-dead.
16950                    uss.mState = UserStartedState.STATE_RUNNING;
16951                    updateStartedUserArrayLocked();
16952                    needStart = true;
16953                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16954                    // This means ACTION_SHUTDOWN has been sent, so we will
16955                    // need to treat this as a new boot of the user.
16956                    uss.mState = UserStartedState.STATE_BOOTING;
16957                    updateStartedUserArrayLocked();
16958                    needStart = true;
16959                }
16960
16961                if (uss.mState == UserStartedState.STATE_BOOTING) {
16962                    // Booting up a new user, need to tell system services about it.
16963                    // Note that this is on the same handler as scheduling of broadcasts,
16964                    // which is important because it needs to go first.
16965                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16966                }
16967
16968                if (foreground) {
16969                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16970                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16971                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16972                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16973                            oldUserId, userId, uss));
16974                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16975                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16976                }
16977
16978                if (needStart) {
16979                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16980                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16981                            | Intent.FLAG_RECEIVER_FOREGROUND);
16982                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16983                    broadcastIntentLocked(null, null, intent,
16984                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16985                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16986                }
16987
16988                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16989                    if (userId != UserHandle.USER_OWNER) {
16990                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16991                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16992                        broadcastIntentLocked(null, null, intent, null,
16993                                new IIntentReceiver.Stub() {
16994                                    public void performReceive(Intent intent, int resultCode,
16995                                            String data, Bundle extras, boolean ordered,
16996                                            boolean sticky, int sendingUser) {
16997                                        userInitialized(uss, userId);
16998                                    }
16999                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17000                                true, false, MY_PID, Process.SYSTEM_UID,
17001                                userId);
17002                        uss.initializing = true;
17003                    } else {
17004                        getUserManagerLocked().makeInitialized(userInfo.id);
17005                    }
17006                }
17007
17008                if (foreground) {
17009                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17010                    if (homeInFront) {
17011                        startHomeActivityLocked(userId);
17012                    } else {
17013                        mStackSupervisor.resumeTopActivitiesLocked();
17014                    }
17015                    EventLogTags.writeAmSwitchUser(userId);
17016                    getUserManagerLocked().userForeground(userId);
17017                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17018                } else {
17019                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17020                }
17021
17022                if (needStart) {
17023                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17024                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17025                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17026                    broadcastIntentLocked(null, null, intent,
17027                            null, new IIntentReceiver.Stub() {
17028                                @Override
17029                                public void performReceive(Intent intent, int resultCode, String data,
17030                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17031                                        throws RemoteException {
17032                                }
17033                            }, 0, null, null,
17034                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17035                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17036                }
17037            }
17038        } finally {
17039            Binder.restoreCallingIdentity(ident);
17040        }
17041
17042        return true;
17043    }
17044
17045    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17046        long ident = Binder.clearCallingIdentity();
17047        try {
17048            Intent intent;
17049            if (oldUserId >= 0) {
17050                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17051                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17052                int count = profiles.size();
17053                for (int i = 0; i < count; i++) {
17054                    int profileUserId = profiles.get(i).id;
17055                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17056                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17057                            | Intent.FLAG_RECEIVER_FOREGROUND);
17058                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17059                    broadcastIntentLocked(null, null, intent,
17060                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17061                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17062                }
17063            }
17064            if (newUserId >= 0) {
17065                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17066                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17067                int count = profiles.size();
17068                for (int i = 0; i < count; i++) {
17069                    int profileUserId = profiles.get(i).id;
17070                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17071                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17072                            | Intent.FLAG_RECEIVER_FOREGROUND);
17073                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17074                    broadcastIntentLocked(null, null, intent,
17075                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17076                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17077                }
17078                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17079                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17080                        | Intent.FLAG_RECEIVER_FOREGROUND);
17081                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17082                broadcastIntentLocked(null, null, intent,
17083                        null, null, 0, null, null,
17084                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17085                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17086            }
17087        } finally {
17088            Binder.restoreCallingIdentity(ident);
17089        }
17090    }
17091
17092    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17093            final int newUserId) {
17094        final int N = mUserSwitchObservers.beginBroadcast();
17095        if (N > 0) {
17096            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17097                int mCount = 0;
17098                @Override
17099                public void sendResult(Bundle data) throws RemoteException {
17100                    synchronized (ActivityManagerService.this) {
17101                        if (mCurUserSwitchCallback == this) {
17102                            mCount++;
17103                            if (mCount == N) {
17104                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17105                            }
17106                        }
17107                    }
17108                }
17109            };
17110            synchronized (this) {
17111                uss.switching = true;
17112                mCurUserSwitchCallback = callback;
17113            }
17114            for (int i=0; i<N; i++) {
17115                try {
17116                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17117                            newUserId, callback);
17118                } catch (RemoteException e) {
17119                }
17120            }
17121        } else {
17122            synchronized (this) {
17123                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17124            }
17125        }
17126        mUserSwitchObservers.finishBroadcast();
17127    }
17128
17129    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17130        synchronized (this) {
17131            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17132            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17133        }
17134    }
17135
17136    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17137        mCurUserSwitchCallback = null;
17138        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17139        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17140                oldUserId, newUserId, uss));
17141    }
17142
17143    void userInitialized(UserStartedState uss, int newUserId) {
17144        completeSwitchAndInitalize(uss, newUserId, true, false);
17145    }
17146
17147    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17148        completeSwitchAndInitalize(uss, newUserId, false, true);
17149    }
17150
17151    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17152            boolean clearInitializing, boolean clearSwitching) {
17153        boolean unfrozen = false;
17154        synchronized (this) {
17155            if (clearInitializing) {
17156                uss.initializing = false;
17157                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17158            }
17159            if (clearSwitching) {
17160                uss.switching = false;
17161            }
17162            if (!uss.switching && !uss.initializing) {
17163                mWindowManager.stopFreezingScreen();
17164                unfrozen = true;
17165            }
17166        }
17167        if (unfrozen) {
17168            final int N = mUserSwitchObservers.beginBroadcast();
17169            for (int i=0; i<N; i++) {
17170                try {
17171                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17172                } catch (RemoteException e) {
17173                }
17174            }
17175            mUserSwitchObservers.finishBroadcast();
17176        }
17177    }
17178
17179    void scheduleStartProfilesLocked() {
17180        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17181            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17182                    DateUtils.SECOND_IN_MILLIS);
17183        }
17184    }
17185
17186    void startProfilesLocked() {
17187        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17188        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17189                mCurrentUserId, false /* enabledOnly */);
17190        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17191        for (UserInfo user : profiles) {
17192            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17193                    && user.id != mCurrentUserId) {
17194                toStart.add(user);
17195            }
17196        }
17197        final int n = toStart.size();
17198        int i = 0;
17199        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17200            startUserInBackground(toStart.get(i).id);
17201        }
17202        if (i < n) {
17203            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17204        }
17205    }
17206
17207    void finishUserBoot(UserStartedState uss) {
17208        synchronized (this) {
17209            if (uss.mState == UserStartedState.STATE_BOOTING
17210                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17211                uss.mState = UserStartedState.STATE_RUNNING;
17212                final int userId = uss.mHandle.getIdentifier();
17213                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17214                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17215                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17216                broadcastIntentLocked(null, null, intent,
17217                        null, null, 0, null, null,
17218                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17219                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17220            }
17221        }
17222    }
17223
17224    void finishUserSwitch(UserStartedState uss) {
17225        synchronized (this) {
17226            finishUserBoot(uss);
17227
17228            startProfilesLocked();
17229
17230            int num = mUserLru.size();
17231            int i = 0;
17232            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17233                Integer oldUserId = mUserLru.get(i);
17234                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17235                if (oldUss == null) {
17236                    // Shouldn't happen, but be sane if it does.
17237                    mUserLru.remove(i);
17238                    num--;
17239                    continue;
17240                }
17241                if (oldUss.mState == UserStartedState.STATE_STOPPING
17242                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17243                    // This user is already stopping, doesn't count.
17244                    num--;
17245                    i++;
17246                    continue;
17247                }
17248                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17249                    // Owner and current can't be stopped, but count as running.
17250                    i++;
17251                    continue;
17252                }
17253                // This is a user to be stopped.
17254                stopUserLocked(oldUserId, null);
17255                num--;
17256                i++;
17257            }
17258        }
17259    }
17260
17261    @Override
17262    public int stopUser(final int userId, final IStopUserCallback callback) {
17263        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17264                != PackageManager.PERMISSION_GRANTED) {
17265            String msg = "Permission Denial: switchUser() from pid="
17266                    + Binder.getCallingPid()
17267                    + ", uid=" + Binder.getCallingUid()
17268                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17269            Slog.w(TAG, msg);
17270            throw new SecurityException(msg);
17271        }
17272        if (userId <= 0) {
17273            throw new IllegalArgumentException("Can't stop primary user " + userId);
17274        }
17275        synchronized (this) {
17276            return stopUserLocked(userId, callback);
17277        }
17278    }
17279
17280    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17281        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17282        if (mCurrentUserId == userId) {
17283            return ActivityManager.USER_OP_IS_CURRENT;
17284        }
17285
17286        final UserStartedState uss = mStartedUsers.get(userId);
17287        if (uss == null) {
17288            // User is not started, nothing to do...  but we do need to
17289            // callback if requested.
17290            if (callback != null) {
17291                mHandler.post(new Runnable() {
17292                    @Override
17293                    public void run() {
17294                        try {
17295                            callback.userStopped(userId);
17296                        } catch (RemoteException e) {
17297                        }
17298                    }
17299                });
17300            }
17301            return ActivityManager.USER_OP_SUCCESS;
17302        }
17303
17304        if (callback != null) {
17305            uss.mStopCallbacks.add(callback);
17306        }
17307
17308        if (uss.mState != UserStartedState.STATE_STOPPING
17309                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17310            uss.mState = UserStartedState.STATE_STOPPING;
17311            updateStartedUserArrayLocked();
17312
17313            long ident = Binder.clearCallingIdentity();
17314            try {
17315                // We are going to broadcast ACTION_USER_STOPPING and then
17316                // once that is done send a final ACTION_SHUTDOWN and then
17317                // stop the user.
17318                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17319                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17320                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17321                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17322                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17323                // This is the result receiver for the final shutdown broadcast.
17324                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17325                    @Override
17326                    public void performReceive(Intent intent, int resultCode, String data,
17327                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17328                        finishUserStop(uss);
17329                    }
17330                };
17331                // This is the result receiver for the initial stopping broadcast.
17332                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17333                    @Override
17334                    public void performReceive(Intent intent, int resultCode, String data,
17335                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17336                        // On to the next.
17337                        synchronized (ActivityManagerService.this) {
17338                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17339                                // Whoops, we are being started back up.  Abort, abort!
17340                                return;
17341                            }
17342                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17343                        }
17344                        mSystemServiceManager.stopUser(userId);
17345                        broadcastIntentLocked(null, null, shutdownIntent,
17346                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17347                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17348                    }
17349                };
17350                // Kick things off.
17351                broadcastIntentLocked(null, null, stoppingIntent,
17352                        null, stoppingReceiver, 0, null, null,
17353                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17354                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17355            } finally {
17356                Binder.restoreCallingIdentity(ident);
17357            }
17358        }
17359
17360        return ActivityManager.USER_OP_SUCCESS;
17361    }
17362
17363    void finishUserStop(UserStartedState uss) {
17364        final int userId = uss.mHandle.getIdentifier();
17365        boolean stopped;
17366        ArrayList<IStopUserCallback> callbacks;
17367        synchronized (this) {
17368            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17369            if (mStartedUsers.get(userId) != uss) {
17370                stopped = false;
17371            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17372                stopped = false;
17373            } else {
17374                stopped = true;
17375                // User can no longer run.
17376                mStartedUsers.remove(userId);
17377                mUserLru.remove(Integer.valueOf(userId));
17378                updateStartedUserArrayLocked();
17379
17380                // Clean up all state and processes associated with the user.
17381                // Kill all the processes for the user.
17382                forceStopUserLocked(userId, "finish user");
17383            }
17384        }
17385
17386        for (int i=0; i<callbacks.size(); i++) {
17387            try {
17388                if (stopped) callbacks.get(i).userStopped(userId);
17389                else callbacks.get(i).userStopAborted(userId);
17390            } catch (RemoteException e) {
17391            }
17392        }
17393
17394        if (stopped) {
17395            mSystemServiceManager.cleanupUser(userId);
17396            synchronized (this) {
17397                mStackSupervisor.removeUserLocked(userId);
17398            }
17399        }
17400    }
17401
17402    @Override
17403    public UserInfo getCurrentUser() {
17404        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17405                != PackageManager.PERMISSION_GRANTED) && (
17406                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17407                != PackageManager.PERMISSION_GRANTED)) {
17408            String msg = "Permission Denial: getCurrentUser() from pid="
17409                    + Binder.getCallingPid()
17410                    + ", uid=" + Binder.getCallingUid()
17411                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17412            Slog.w(TAG, msg);
17413            throw new SecurityException(msg);
17414        }
17415        synchronized (this) {
17416            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17417        }
17418    }
17419
17420    int getCurrentUserIdLocked() {
17421        return mCurrentUserId;
17422    }
17423
17424    @Override
17425    public boolean isUserRunning(int userId, boolean orStopped) {
17426        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17427                != PackageManager.PERMISSION_GRANTED) {
17428            String msg = "Permission Denial: isUserRunning() from pid="
17429                    + Binder.getCallingPid()
17430                    + ", uid=" + Binder.getCallingUid()
17431                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17432            Slog.w(TAG, msg);
17433            throw new SecurityException(msg);
17434        }
17435        synchronized (this) {
17436            return isUserRunningLocked(userId, orStopped);
17437        }
17438    }
17439
17440    boolean isUserRunningLocked(int userId, boolean orStopped) {
17441        UserStartedState state = mStartedUsers.get(userId);
17442        if (state == null) {
17443            return false;
17444        }
17445        if (orStopped) {
17446            return true;
17447        }
17448        return state.mState != UserStartedState.STATE_STOPPING
17449                && state.mState != UserStartedState.STATE_SHUTDOWN;
17450    }
17451
17452    @Override
17453    public int[] getRunningUserIds() {
17454        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17455                != PackageManager.PERMISSION_GRANTED) {
17456            String msg = "Permission Denial: isUserRunning() from pid="
17457                    + Binder.getCallingPid()
17458                    + ", uid=" + Binder.getCallingUid()
17459                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17460            Slog.w(TAG, msg);
17461            throw new SecurityException(msg);
17462        }
17463        synchronized (this) {
17464            return mStartedUserArray;
17465        }
17466    }
17467
17468    private void updateStartedUserArrayLocked() {
17469        int num = 0;
17470        for (int i=0; i<mStartedUsers.size();  i++) {
17471            UserStartedState uss = mStartedUsers.valueAt(i);
17472            // This list does not include stopping users.
17473            if (uss.mState != UserStartedState.STATE_STOPPING
17474                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17475                num++;
17476            }
17477        }
17478        mStartedUserArray = new int[num];
17479        num = 0;
17480        for (int i=0; i<mStartedUsers.size();  i++) {
17481            UserStartedState uss = mStartedUsers.valueAt(i);
17482            if (uss.mState != UserStartedState.STATE_STOPPING
17483                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17484                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17485                num++;
17486            }
17487        }
17488    }
17489
17490    @Override
17491    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17492        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17493                != PackageManager.PERMISSION_GRANTED) {
17494            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17495                    + Binder.getCallingPid()
17496                    + ", uid=" + Binder.getCallingUid()
17497                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17498            Slog.w(TAG, msg);
17499            throw new SecurityException(msg);
17500        }
17501
17502        mUserSwitchObservers.register(observer);
17503    }
17504
17505    @Override
17506    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17507        mUserSwitchObservers.unregister(observer);
17508    }
17509
17510    private boolean userExists(int userId) {
17511        if (userId == 0) {
17512            return true;
17513        }
17514        UserManagerService ums = getUserManagerLocked();
17515        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17516    }
17517
17518    int[] getUsersLocked() {
17519        UserManagerService ums = getUserManagerLocked();
17520        return ums != null ? ums.getUserIds() : new int[] { 0 };
17521    }
17522
17523    UserManagerService getUserManagerLocked() {
17524        if (mUserManager == null) {
17525            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17526            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17527        }
17528        return mUserManager;
17529    }
17530
17531    private int applyUserId(int uid, int userId) {
17532        return UserHandle.getUid(userId, uid);
17533    }
17534
17535    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17536        if (info == null) return null;
17537        ApplicationInfo newInfo = new ApplicationInfo(info);
17538        newInfo.uid = applyUserId(info.uid, userId);
17539        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17540                + info.packageName;
17541        return newInfo;
17542    }
17543
17544    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17545        if (aInfo == null
17546                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17547            return aInfo;
17548        }
17549
17550        ActivityInfo info = new ActivityInfo(aInfo);
17551        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17552        return info;
17553    }
17554
17555    private final class LocalService extends ActivityManagerInternal {
17556        @Override
17557        public void goingToSleep() {
17558            ActivityManagerService.this.goingToSleep();
17559        }
17560
17561        @Override
17562        public void wakingUp() {
17563            ActivityManagerService.this.wakingUp();
17564        }
17565    }
17566
17567    /**
17568     * An implementation of IAppTask, that allows an app to manage its own tasks via
17569     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17570     * only the process that calls getAppTasks() can call the AppTask methods.
17571     */
17572    class AppTaskImpl extends IAppTask.Stub {
17573        private int mTaskId;
17574        private int mCallingUid;
17575
17576        public AppTaskImpl(int taskId, int callingUid) {
17577            mTaskId = taskId;
17578            mCallingUid = callingUid;
17579        }
17580
17581        @Override
17582        public void finishAndRemoveTask() {
17583            // Ensure that we are called from the same process that created this AppTask
17584            if (mCallingUid != Binder.getCallingUid()) {
17585                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17586                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17587                return;
17588            }
17589
17590            synchronized (ActivityManagerService.this) {
17591                long origId = Binder.clearCallingIdentity();
17592                try {
17593                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17594                    if (tr != null) {
17595                        // Only kill the process if we are not a new document
17596                        int flags = tr.getBaseIntent().getFlags();
17597                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17598                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17599                        removeTaskByIdLocked(mTaskId,
17600                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17601                    }
17602                } finally {
17603                    Binder.restoreCallingIdentity(origId);
17604                }
17605            }
17606        }
17607
17608        @Override
17609        public ActivityManager.RecentTaskInfo getTaskInfo() {
17610            // Ensure that we are called from the same process that created this AppTask
17611            if (mCallingUid != Binder.getCallingUid()) {
17612                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17613                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17614                return null;
17615            }
17616
17617            synchronized (ActivityManagerService.this) {
17618                long origId = Binder.clearCallingIdentity();
17619                try {
17620                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17621                    if (tr != null) {
17622                        return createRecentTaskInfoFromTaskRecord(tr);
17623                    }
17624                } finally {
17625                    Binder.restoreCallingIdentity(origId);
17626                }
17627                return null;
17628            }
17629        }
17630    }
17631}
17632