ActivityManagerService.java revision d908edd810dd22d8ec512a19c32637df464e9d0a
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.graphics.Bitmap;
142import android.net.Proxy;
143import android.net.ProxyInfo;
144import android.net.Uri;
145import android.os.Binder;
146import android.os.Build;
147import android.os.Bundle;
148import android.os.Debug;
149import android.os.DropBoxManager;
150import android.os.Environment;
151import android.os.FactoryTest;
152import android.os.FileObserver;
153import android.os.FileUtils;
154import android.os.Handler;
155import android.os.IBinder;
156import android.os.IPermissionController;
157import android.os.IRemoteCallback;
158import android.os.IUserManager;
159import android.os.Looper;
160import android.os.Message;
161import android.os.Parcel;
162import android.os.ParcelFileDescriptor;
163import android.os.Process;
164import android.os.RemoteCallbackList;
165import android.os.RemoteException;
166import android.os.SELinux;
167import android.os.ServiceManager;
168import android.os.StrictMode;
169import android.os.SystemClock;
170import android.os.SystemProperties;
171import android.os.UpdateLock;
172import android.os.UserHandle;
173import android.provider.Settings;
174import android.text.format.DateUtils;
175import android.text.format.Time;
176import android.util.AtomicFile;
177import android.util.EventLog;
178import android.util.Log;
179import android.util.Pair;
180import android.util.PrintWriterPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.TimeUtils;
184import android.util.Xml;
185import android.view.Gravity;
186import android.view.LayoutInflater;
187import android.view.View;
188import android.view.WindowManager;
189
190import java.io.BufferedInputStream;
191import java.io.BufferedOutputStream;
192import java.io.DataInputStream;
193import java.io.DataOutputStream;
194import java.io.File;
195import java.io.FileDescriptor;
196import java.io.FileInputStream;
197import java.io.FileNotFoundException;
198import java.io.FileOutputStream;
199import java.io.IOException;
200import java.io.InputStreamReader;
201import java.io.PrintWriter;
202import java.io.StringWriter;
203import java.lang.ref.WeakReference;
204import java.util.ArrayList;
205import java.util.Arrays;
206import java.util.Collections;
207import java.util.Comparator;
208import java.util.HashMap;
209import java.util.HashSet;
210import java.util.Iterator;
211import java.util.List;
212import java.util.Locale;
213import java.util.Map;
214import java.util.Set;
215import java.util.concurrent.atomic.AtomicBoolean;
216import java.util.concurrent.atomic.AtomicLong;
217
218public final class ActivityManagerService extends ActivityManagerNative
219        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
220    private static final String USER_DATA_DIR = "/data/user/";
221    static final String TAG = "ActivityManager";
222    static final String TAG_MU = "ActivityManagerServiceMU";
223    static final boolean DEBUG = false;
224    static final boolean localLOGV = DEBUG;
225    static final boolean DEBUG_BACKUP = localLOGV || false;
226    static final boolean DEBUG_BROADCAST = localLOGV || false;
227    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_CLEANUP = localLOGV || false;
230    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
231    static final boolean DEBUG_FOCUS = false;
232    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
233    static final boolean DEBUG_MU = localLOGV || false;
234    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
235    static final boolean DEBUG_LRU = localLOGV || false;
236    static final boolean DEBUG_PAUSE = localLOGV || false;
237    static final boolean DEBUG_POWER = localLOGV || false;
238    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
239    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
240    static final boolean DEBUG_PROCESSES = localLOGV || false;
241    static final boolean DEBUG_PROVIDER = localLOGV || false;
242    static final boolean DEBUG_RESULTS = localLOGV || false;
243    static final boolean DEBUG_SERVICE = localLOGV || false;
244    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
245    static final boolean DEBUG_STACK = localLOGV || false;
246    static final boolean DEBUG_SWITCH = localLOGV || false;
247    static final boolean DEBUG_TASKS = localLOGV || false;
248    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
249    static final boolean DEBUG_TRANSITION = localLOGV || false;
250    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
251    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
252    static final boolean DEBUG_VISBILITY = localLOGV || false;
253    static final boolean DEBUG_PSS = localLOGV || false;
254    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
255    static final boolean VALIDATE_TOKENS = false;
256    static final boolean SHOW_ACTIVITY_START_TIME = true;
257
258    // Control over CPU and battery monitoring.
259    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
260    static final boolean MONITOR_CPU_USAGE = true;
261    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
262    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
263    static final boolean MONITOR_THREAD_CPU_USAGE = false;
264
265    // The flags that are set for all calls we make to the package manager.
266    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
267
268    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
269
270    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
271
272    // Maximum number of recent tasks that we can remember.
273    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
274
275    // Maximum number recent bitmaps to keep in memory.
276    static final int MAX_RECENT_BITMAPS = 5;
277
278    // Amount of time after a call to stopAppSwitches() during which we will
279    // prevent further untrusted switches from happening.
280    static final long APP_SWITCH_DELAY_TIME = 5*1000;
281
282    // How long we wait for a launched process to attach to the activity manager
283    // before we decide it's never going to come up for real.
284    static final int PROC_START_TIMEOUT = 10*1000;
285
286    // How long we wait for a launched process to attach to the activity manager
287    // before we decide it's never going to come up for real, when the process was
288    // started with a wrapper for instrumentation (such as Valgrind) because it
289    // could take much longer than usual.
290    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
291
292    // How long to wait after going idle before forcing apps to GC.
293    static final int GC_TIMEOUT = 5*1000;
294
295    // The minimum amount of time between successive GC requests for a process.
296    static final int GC_MIN_INTERVAL = 60*1000;
297
298    // The minimum amount of time between successive PSS requests for a process.
299    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
300
301    // The minimum amount of time between successive PSS requests for a process
302    // when the request is due to the memory state being lowered.
303    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
304
305    // The rate at which we check for apps using excessive power -- 15 mins.
306    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
307
308    // The minimum sample duration we will allow before deciding we have
309    // enough data on wake locks to start killing things.
310    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
311
312    // The minimum sample duration we will allow before deciding we have
313    // enough data on CPU usage to start killing things.
314    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
315
316    // How long we allow a receiver to run before giving up on it.
317    static final int BROADCAST_FG_TIMEOUT = 10*1000;
318    static final int BROADCAST_BG_TIMEOUT = 60*1000;
319
320    // How long we wait until we timeout on key dispatching.
321    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
322
323    // How long we wait until we timeout on key dispatching during instrumentation.
324    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
325
326    // Amount of time we wait for observers to handle a user switch before
327    // giving up on them and unfreezing the screen.
328    static final int USER_SWITCH_TIMEOUT = 2*1000;
329
330    // Maximum number of users we allow to be running at a time.
331    static final int MAX_RUNNING_USERS = 3;
332
333    // How long to wait in getAssistContextExtras for the activity and foreground services
334    // to respond with the result.
335    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
336
337    // Maximum number of persisted Uri grants a package is allowed
338    static final int MAX_PERSISTED_URI_GRANTS = 128;
339
340    static final int MY_PID = Process.myPid();
341
342    static final String[] EMPTY_STRING_ARRAY = new String[0];
343
344    // How many bytes to write into the dropbox log before truncating
345    static final int DROPBOX_MAX_SIZE = 256 * 1024;
346
347    /** All system services */
348    SystemServiceManager mSystemServiceManager;
349
350    /** Run all ActivityStacks through this */
351    ActivityStackSupervisor mStackSupervisor;
352
353    public IntentFirewall mIntentFirewall;
354
355    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
356    // default actuion automatically.  Important for devices without direct input
357    // devices.
358    private boolean mShowDialogs = true;
359
360    /**
361     * Description of a request to start a new activity, which has been held
362     * due to app switches being disabled.
363     */
364    static class PendingActivityLaunch {
365        final ActivityRecord r;
366        final ActivityRecord sourceRecord;
367        final int startFlags;
368        final ActivityStack stack;
369
370        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
371                int _startFlags, ActivityStack _stack) {
372            r = _r;
373            sourceRecord = _sourceRecord;
374            startFlags = _startFlags;
375            stack = _stack;
376        }
377    }
378
379    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
380            = new ArrayList<PendingActivityLaunch>();
381
382    BroadcastQueue mFgBroadcastQueue;
383    BroadcastQueue mBgBroadcastQueue;
384    // Convenient for easy iteration over the queues. Foreground is first
385    // so that dispatch of foreground broadcasts gets precedence.
386    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
387
388    BroadcastQueue broadcastQueueForIntent(Intent intent) {
389        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
390        if (DEBUG_BACKGROUND_BROADCAST) {
391            Slog.i(TAG, "Broadcast intent " + intent + " on "
392                    + (isFg ? "foreground" : "background")
393                    + " queue");
394        }
395        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
396    }
397
398    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
399        for (BroadcastQueue queue : mBroadcastQueues) {
400            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
401            if (r != null) {
402                return r;
403            }
404        }
405        return null;
406    }
407
408    /**
409     * Activity we have told the window manager to have key focus.
410     */
411    ActivityRecord mFocusedActivity = null;
412
413    /**
414     * List of intents that were used to start the most recent tasks.
415     */
416    ArrayList<TaskRecord> mRecentTasks;
417
418    public class PendingAssistExtras extends Binder implements Runnable {
419        public final ActivityRecord activity;
420        public boolean haveResult = false;
421        public Bundle result = null;
422        public PendingAssistExtras(ActivityRecord _activity) {
423            activity = _activity;
424        }
425        @Override
426        public void run() {
427            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
428            synchronized (this) {
429                haveResult = true;
430                notifyAll();
431            }
432        }
433    }
434
435    final ArrayList<PendingAssistExtras> mPendingAssistExtras
436            = new ArrayList<PendingAssistExtras>();
437
438    /**
439     * Process management.
440     */
441    final ProcessList mProcessList = new ProcessList();
442
443    /**
444     * All of the applications we currently have running organized by name.
445     * The keys are strings of the application package name (as
446     * returned by the package manager), and the keys are ApplicationRecord
447     * objects.
448     */
449    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
450
451    /**
452     * Tracking long-term execution of processes to look for abuse and other
453     * bad app behavior.
454     */
455    final ProcessStatsService mProcessStats;
456
457    /**
458     * The currently running isolated processes.
459     */
460    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
461
462    /**
463     * Counter for assigning isolated process uids, to avoid frequently reusing the
464     * same ones.
465     */
466    int mNextIsolatedProcessUid = 0;
467
468    /**
469     * The currently running heavy-weight process, if any.
470     */
471    ProcessRecord mHeavyWeightProcess = null;
472
473    /**
474     * The last time that various processes have crashed.
475     */
476    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
477
478    /**
479     * Information about a process that is currently marked as bad.
480     */
481    static final class BadProcessInfo {
482        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
483            this.time = time;
484            this.shortMsg = shortMsg;
485            this.longMsg = longMsg;
486            this.stack = stack;
487        }
488
489        final long time;
490        final String shortMsg;
491        final String longMsg;
492        final String stack;
493    }
494
495    /**
496     * Set of applications that we consider to be bad, and will reject
497     * incoming broadcasts from (which the user has no control over).
498     * Processes are added to this set when they have crashed twice within
499     * a minimum amount of time; they are removed from it when they are
500     * later restarted (hopefully due to some user action).  The value is the
501     * time it was added to the list.
502     */
503    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
504
505    /**
506     * All of the processes we currently have running organized by pid.
507     * The keys are the pid running the application.
508     *
509     * <p>NOTE: This object is protected by its own lock, NOT the global
510     * activity manager lock!
511     */
512    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
513
514    /**
515     * All of the processes that have been forced to be foreground.  The key
516     * is the pid of the caller who requested it (we hold a death
517     * link on it).
518     */
519    abstract class ForegroundToken implements IBinder.DeathRecipient {
520        int pid;
521        IBinder token;
522    }
523    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
524
525    /**
526     * List of records for processes that someone had tried to start before the
527     * system was ready.  We don't start them at that point, but ensure they
528     * are started by the time booting is complete.
529     */
530    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
531
532    /**
533     * List of persistent applications that are in the process
534     * of being started.
535     */
536    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * Processes that are being forcibly torn down.
540     */
541    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * List of running applications, sorted by recent usage.
545     * The first entry in the list is the least recently used.
546     */
547    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
548
549    /**
550     * Where in mLruProcesses that the processes hosting activities start.
551     */
552    int mLruProcessActivityStart = 0;
553
554    /**
555     * Where in mLruProcesses that the processes hosting services start.
556     * This is after (lower index) than mLruProcessesActivityStart.
557     */
558    int mLruProcessServiceStart = 0;
559
560    /**
561     * List of processes that should gc as soon as things are idle.
562     */
563    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
564
565    /**
566     * Processes we want to collect PSS data from.
567     */
568    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
569
570    /**
571     * Last time we requested PSS data of all processes.
572     */
573    long mLastFullPssTime = SystemClock.uptimeMillis();
574
575    /**
576     * If set, the next time we collect PSS data we should do a full collection
577     * with data from native processes and the kernel.
578     */
579    boolean mFullPssPending = false;
580
581    /**
582     * This is the process holding what we currently consider to be
583     * the "home" activity.
584     */
585    ProcessRecord mHomeProcess;
586
587    /**
588     * This is the process holding the activity the user last visited that
589     * is in a different process from the one they are currently in.
590     */
591    ProcessRecord mPreviousProcess;
592
593    /**
594     * The time at which the previous process was last visible.
595     */
596    long mPreviousProcessVisibleTime;
597
598    /**
599     * Which uses have been started, so are allowed to run code.
600     */
601    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
602
603    /**
604     * LRU list of history of current users.  Most recently current is at the end.
605     */
606    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
607
608    /**
609     * Constant array of the users that are currently started.
610     */
611    int[] mStartedUserArray = new int[] { 0 };
612
613    /**
614     * Registered observers of the user switching mechanics.
615     */
616    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
617            = new RemoteCallbackList<IUserSwitchObserver>();
618
619    /**
620     * Currently active user switch.
621     */
622    Object mCurUserSwitchCallback;
623
624    /**
625     * Packages that the user has asked to have run in screen size
626     * compatibility mode instead of filling the screen.
627     */
628    final CompatModePackages mCompatModePackages;
629
630    /**
631     * Set of IntentSenderRecord objects that are currently active.
632     */
633    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
634            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
635
636    /**
637     * Fingerprints (hashCode()) of stack traces that we've
638     * already logged DropBox entries for.  Guarded by itself.  If
639     * something (rogue user app) forces this over
640     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
641     */
642    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
643    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
644
645    /**
646     * Strict Mode background batched logging state.
647     *
648     * The string buffer is guarded by itself, and its lock is also
649     * used to determine if another batched write is already
650     * in-flight.
651     */
652    private final StringBuilder mStrictModeBuffer = new StringBuilder();
653
654    /**
655     * Keeps track of all IIntentReceivers that have been registered for
656     * broadcasts.  Hash keys are the receiver IBinder, hash value is
657     * a ReceiverList.
658     */
659    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
660            new HashMap<IBinder, ReceiverList>();
661
662    /**
663     * Resolver for broadcast intents to registered receivers.
664     * Holds BroadcastFilter (subclass of IntentFilter).
665     */
666    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
667            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
668        @Override
669        protected boolean allowFilterResult(
670                BroadcastFilter filter, List<BroadcastFilter> dest) {
671            IBinder target = filter.receiverList.receiver.asBinder();
672            for (int i=dest.size()-1; i>=0; i--) {
673                if (dest.get(i).receiverList.receiver.asBinder() == target) {
674                    return false;
675                }
676            }
677            return true;
678        }
679
680        @Override
681        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
682            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
683                    || userId == filter.owningUserId) {
684                return super.newResult(filter, match, userId);
685            }
686            return null;
687        }
688
689        @Override
690        protected BroadcastFilter[] newArray(int size) {
691            return new BroadcastFilter[size];
692        }
693
694        @Override
695        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
696            return packageName.equals(filter.packageName);
697        }
698    };
699
700    /**
701     * State of all active sticky broadcasts per user.  Keys are the action of the
702     * sticky Intent, values are an ArrayList of all broadcasted intents with
703     * that action (which should usually be one).  The SparseArray is keyed
704     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
705     * for stickies that are sent to all users.
706     */
707    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
708            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
709
710    final ActiveServices mServices;
711
712    /**
713     * Backup/restore process management
714     */
715    String mBackupAppName = null;
716    BackupRecord mBackupTarget = null;
717
718    final ProviderMap mProviderMap;
719
720    /**
721     * List of content providers who have clients waiting for them.  The
722     * application is currently being launched and the provider will be
723     * removed from this list once it is published.
724     */
725    final ArrayList<ContentProviderRecord> mLaunchingProviders
726            = new ArrayList<ContentProviderRecord>();
727
728    /**
729     * File storing persisted {@link #mGrantedUriPermissions}.
730     */
731    private final AtomicFile mGrantFile;
732
733    /** XML constants used in {@link #mGrantFile} */
734    private static final String TAG_URI_GRANTS = "uri-grants";
735    private static final String TAG_URI_GRANT = "uri-grant";
736    private static final String ATTR_USER_HANDLE = "userHandle";
737    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
738    private static final String ATTR_TARGET_USER_ID = "targetUserId";
739    private static final String ATTR_SOURCE_PKG = "sourcePkg";
740    private static final String ATTR_TARGET_PKG = "targetPkg";
741    private static final String ATTR_URI = "uri";
742    private static final String ATTR_MODE_FLAGS = "modeFlags";
743    private static final String ATTR_CREATED_TIME = "createdTime";
744    private static final String ATTR_PREFIX = "prefix";
745
746    /**
747     * Global set of specific {@link Uri} permissions that have been granted.
748     * This optimized lookup structure maps from {@link UriPermission#targetUid}
749     * to {@link UriPermission#uri} to {@link UriPermission}.
750     */
751    @GuardedBy("this")
752    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
753            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
754
755    public static class GrantUri {
756        public final int sourceUserId;
757        public final Uri uri;
758        public boolean prefix;
759
760        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
761            this.sourceUserId = sourceUserId;
762            this.uri = uri;
763            this.prefix = prefix;
764        }
765
766        @Override
767        public int hashCode() {
768            return toString().hashCode();
769        }
770
771        @Override
772        public boolean equals(Object o) {
773            if (o instanceof GrantUri) {
774                GrantUri other = (GrantUri) o;
775                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
776                        && prefix == other.prefix;
777            }
778            return false;
779        }
780
781        @Override
782        public String toString() {
783            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
784            if (prefix) result += " [prefix]";
785            return result;
786        }
787
788        public String toSafeString() {
789            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
790            if (prefix) result += " [prefix]";
791            return result;
792        }
793
794        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
795            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
796                    ContentProvider.getUriWithoutUserId(uri), false);
797        }
798    }
799
800    CoreSettingsObserver mCoreSettingsObserver;
801
802    /**
803     * Thread-local storage used to carry caller permissions over through
804     * indirect content-provider access.
805     */
806    private class Identity {
807        public int pid;
808        public int uid;
809
810        Identity(int _pid, int _uid) {
811            pid = _pid;
812            uid = _uid;
813        }
814    }
815
816    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
817
818    /**
819     * All information we have collected about the runtime performance of
820     * any user id that can impact battery performance.
821     */
822    final BatteryStatsService mBatteryStatsService;
823
824    /**
825     * Information about component usage
826     */
827    final UsageStatsService mUsageStatsService;
828
829    /**
830     * Information about and control over application operations
831     */
832    final AppOpsService mAppOpsService;
833
834    /**
835     * Save recent tasks information across reboots.
836     */
837    final TaskPersister mTaskPersister;
838
839    /**
840     * Current configuration information.  HistoryRecord objects are given
841     * a reference to this object to indicate which configuration they are
842     * currently running in, so this object must be kept immutable.
843     */
844    Configuration mConfiguration = new Configuration();
845
846    /**
847     * Current sequencing integer of the configuration, for skipping old
848     * configurations.
849     */
850    int mConfigurationSeq = 0;
851
852    /**
853     * Hardware-reported OpenGLES version.
854     */
855    final int GL_ES_VERSION;
856
857    /**
858     * List of initialization arguments to pass to all processes when binding applications to them.
859     * For example, references to the commonly used services.
860     */
861    HashMap<String, IBinder> mAppBindArgs;
862
863    /**
864     * Temporary to avoid allocations.  Protected by main lock.
865     */
866    final StringBuilder mStringBuilder = new StringBuilder(256);
867
868    /**
869     * Used to control how we initialize the service.
870     */
871    ComponentName mTopComponent;
872    String mTopAction = Intent.ACTION_MAIN;
873    String mTopData;
874    boolean mProcessesReady = false;
875    boolean mSystemReady = false;
876    boolean mBooting = false;
877    boolean mWaitingUpdate = false;
878    boolean mDidUpdate = false;
879    boolean mOnBattery = false;
880    boolean mLaunchWarningShown = false;
881
882    Context mContext;
883
884    int mFactoryTest;
885
886    boolean mCheckedForSetup;
887
888    /**
889     * The time at which we will allow normal application switches again,
890     * after a call to {@link #stopAppSwitches()}.
891     */
892    long mAppSwitchesAllowedTime;
893
894    /**
895     * This is set to true after the first switch after mAppSwitchesAllowedTime
896     * is set; any switches after that will clear the time.
897     */
898    boolean mDidAppSwitch;
899
900    /**
901     * Last time (in realtime) at which we checked for power usage.
902     */
903    long mLastPowerCheckRealtime;
904
905    /**
906     * Last time (in uptime) at which we checked for power usage.
907     */
908    long mLastPowerCheckUptime;
909
910    /**
911     * Set while we are wanting to sleep, to prevent any
912     * activities from being started/resumed.
913     */
914    private boolean mSleeping = false;
915
916    /**
917     * Set while we are running a voice interaction.  This overrides
918     * sleeping while it is active.
919     */
920    private boolean mRunningVoice = false;
921
922    /**
923     * State of external calls telling us if the device is asleep.
924     */
925    private boolean mWentToSleep = false;
926
927    /**
928     * State of external call telling us if the lock screen is shown.
929     */
930    private boolean mLockScreenShown = false;
931
932    /**
933     * Set if we are shutting down the system, similar to sleeping.
934     */
935    boolean mShuttingDown = false;
936
937    /**
938     * Current sequence id for oom_adj computation traversal.
939     */
940    int mAdjSeq = 0;
941
942    /**
943     * Current sequence id for process LRU updating.
944     */
945    int mLruSeq = 0;
946
947    /**
948     * Keep track of the non-cached/empty process we last found, to help
949     * determine how to distribute cached/empty processes next time.
950     */
951    int mNumNonCachedProcs = 0;
952
953    /**
954     * Keep track of the number of cached hidden procs, to balance oom adj
955     * distribution between those and empty procs.
956     */
957    int mNumCachedHiddenProcs = 0;
958
959    /**
960     * Keep track of the number of service processes we last found, to
961     * determine on the next iteration which should be B services.
962     */
963    int mNumServiceProcs = 0;
964    int mNewNumAServiceProcs = 0;
965    int mNewNumServiceProcs = 0;
966
967    /**
968     * Allow the current computed overall memory level of the system to go down?
969     * This is set to false when we are killing processes for reasons other than
970     * memory management, so that the now smaller process list will not be taken as
971     * an indication that memory is tighter.
972     */
973    boolean mAllowLowerMemLevel = false;
974
975    /**
976     * The last computed memory level, for holding when we are in a state that
977     * processes are going away for other reasons.
978     */
979    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
980
981    /**
982     * The last total number of process we have, to determine if changes actually look
983     * like a shrinking number of process due to lower RAM.
984     */
985    int mLastNumProcesses;
986
987    /**
988     * The uptime of the last time we performed idle maintenance.
989     */
990    long mLastIdleTime = SystemClock.uptimeMillis();
991
992    /**
993     * Total time spent with RAM that has been added in the past since the last idle time.
994     */
995    long mLowRamTimeSinceLastIdle = 0;
996
997    /**
998     * If RAM is currently low, when that horrible situation started.
999     */
1000    long mLowRamStartTime = 0;
1001
1002    /**
1003     * For reporting to battery stats the current top application.
1004     */
1005    private String mCurResumedPackage = null;
1006    private int mCurResumedUid = -1;
1007
1008    /**
1009     * For reporting to battery stats the apps currently running foreground
1010     * service.  The ProcessMap is package/uid tuples; each of these contain
1011     * an array of the currently foreground processes.
1012     */
1013    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1014            = new ProcessMap<ArrayList<ProcessRecord>>();
1015
1016    /**
1017     * This is set if we had to do a delayed dexopt of an app before launching
1018     * it, to increase the ANR timeouts in that case.
1019     */
1020    boolean mDidDexOpt;
1021
1022    /**
1023     * Set if the systemServer made a call to enterSafeMode.
1024     */
1025    boolean mSafeMode;
1026
1027    String mDebugApp = null;
1028    boolean mWaitForDebugger = false;
1029    boolean mDebugTransient = false;
1030    String mOrigDebugApp = null;
1031    boolean mOrigWaitForDebugger = false;
1032    boolean mAlwaysFinishActivities = false;
1033    IActivityController mController = null;
1034    String mProfileApp = null;
1035    ProcessRecord mProfileProc = null;
1036    String mProfileFile;
1037    ParcelFileDescriptor mProfileFd;
1038    int mProfileType = 0;
1039    boolean mAutoStopProfiler = false;
1040    String mOpenGlTraceApp = null;
1041
1042    static class ProcessChangeItem {
1043        static final int CHANGE_ACTIVITIES = 1<<0;
1044        static final int CHANGE_PROCESS_STATE = 1<<1;
1045        int changes;
1046        int uid;
1047        int pid;
1048        int processState;
1049        boolean foregroundActivities;
1050    }
1051
1052    final RemoteCallbackList<IProcessObserver> mProcessObservers
1053            = new RemoteCallbackList<IProcessObserver>();
1054    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1055
1056    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1057            = new ArrayList<ProcessChangeItem>();
1058    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1059            = new ArrayList<ProcessChangeItem>();
1060
1061    /**
1062     * Runtime CPU use collection thread.  This object's lock is used to
1063     * protect all related state.
1064     */
1065    final Thread mProcessCpuThread;
1066
1067    /**
1068     * Used to collect process stats when showing not responding dialog.
1069     * Protected by mProcessCpuThread.
1070     */
1071    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1072            MONITOR_THREAD_CPU_USAGE);
1073    final AtomicLong mLastCpuTime = new AtomicLong(0);
1074    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1075
1076    long mLastWriteTime = 0;
1077
1078    /**
1079     * Used to retain an update lock when the foreground activity is in
1080     * immersive mode.
1081     */
1082    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1083
1084    /**
1085     * Set to true after the system has finished booting.
1086     */
1087    boolean mBooted = false;
1088
1089    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1090    int mProcessLimitOverride = -1;
1091
1092    WindowManagerService mWindowManager;
1093
1094    final ActivityThread mSystemThread;
1095
1096    int mCurrentUserId = 0;
1097    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1098    private UserManagerService mUserManager;
1099
1100    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1101        final ProcessRecord mApp;
1102        final int mPid;
1103        final IApplicationThread mAppThread;
1104
1105        AppDeathRecipient(ProcessRecord app, int pid,
1106                IApplicationThread thread) {
1107            if (localLOGV) Slog.v(
1108                TAG, "New death recipient " + this
1109                + " for thread " + thread.asBinder());
1110            mApp = app;
1111            mPid = pid;
1112            mAppThread = thread;
1113        }
1114
1115        @Override
1116        public void binderDied() {
1117            if (localLOGV) Slog.v(
1118                TAG, "Death received in " + this
1119                + " for thread " + mAppThread.asBinder());
1120            synchronized(ActivityManagerService.this) {
1121                appDiedLocked(mApp, mPid, mAppThread);
1122            }
1123        }
1124    }
1125
1126    static final int SHOW_ERROR_MSG = 1;
1127    static final int SHOW_NOT_RESPONDING_MSG = 2;
1128    static final int SHOW_FACTORY_ERROR_MSG = 3;
1129    static final int UPDATE_CONFIGURATION_MSG = 4;
1130    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1131    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1132    static final int SERVICE_TIMEOUT_MSG = 12;
1133    static final int UPDATE_TIME_ZONE = 13;
1134    static final int SHOW_UID_ERROR_MSG = 14;
1135    static final int IM_FEELING_LUCKY_MSG = 15;
1136    static final int PROC_START_TIMEOUT_MSG = 20;
1137    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1138    static final int KILL_APPLICATION_MSG = 22;
1139    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1140    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1141    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1142    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1143    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1144    static final int CLEAR_DNS_CACHE_MSG = 28;
1145    static final int UPDATE_HTTP_PROXY_MSG = 29;
1146    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1147    static final int DISPATCH_PROCESSES_CHANGED = 31;
1148    static final int DISPATCH_PROCESS_DIED = 32;
1149    static final int REPORT_MEM_USAGE_MSG = 33;
1150    static final int REPORT_USER_SWITCH_MSG = 34;
1151    static final int CONTINUE_USER_SWITCH_MSG = 35;
1152    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1153    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1154    static final int PERSIST_URI_GRANTS_MSG = 38;
1155    static final int REQUEST_ALL_PSS_MSG = 39;
1156    static final int START_PROFILES_MSG = 40;
1157    static final int UPDATE_TIME = 41;
1158    static final int SYSTEM_USER_START_MSG = 42;
1159    static final int SYSTEM_USER_CURRENT_MSG = 43;
1160
1161    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1162    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1163    static final int FIRST_COMPAT_MODE_MSG = 300;
1164    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1165
1166    AlertDialog mUidAlert;
1167    CompatModeDialog mCompatModeDialog;
1168    long mLastMemUsageReportTime = 0;
1169
1170    private LockToAppRequestDialog mLockToAppRequest;
1171
1172    /**
1173     * Flag whether the current user is a "monkey", i.e. whether
1174     * the UI is driven by a UI automation tool.
1175     */
1176    private boolean mUserIsMonkey;
1177
1178    final ServiceThread mHandlerThread;
1179    final MainHandler mHandler;
1180
1181    final class MainHandler extends Handler {
1182        public MainHandler(Looper looper) {
1183            super(looper, null, true);
1184        }
1185
1186        @Override
1187        public void handleMessage(Message msg) {
1188            switch (msg.what) {
1189            case SHOW_ERROR_MSG: {
1190                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1191                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1192                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1193                synchronized (ActivityManagerService.this) {
1194                    ProcessRecord proc = (ProcessRecord)data.get("app");
1195                    AppErrorResult res = (AppErrorResult) data.get("result");
1196                    if (proc != null && proc.crashDialog != null) {
1197                        Slog.e(TAG, "App already has crash dialog: " + proc);
1198                        if (res != null) {
1199                            res.set(0);
1200                        }
1201                        return;
1202                    }
1203                    if (!showBackground && UserHandle.getAppId(proc.uid)
1204                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1205                            && proc.pid != MY_PID) {
1206                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1207                        if (res != null) {
1208                            res.set(0);
1209                        }
1210                        return;
1211                    }
1212                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1213                        Dialog d = new AppErrorDialog(mContext,
1214                                ActivityManagerService.this, res, proc);
1215                        d.show();
1216                        proc.crashDialog = d;
1217                    } else {
1218                        // The device is asleep, so just pretend that the user
1219                        // saw a crash dialog and hit "force quit".
1220                        if (res != null) {
1221                            res.set(0);
1222                        }
1223                    }
1224                }
1225
1226                ensureBootCompleted();
1227            } break;
1228            case SHOW_NOT_RESPONDING_MSG: {
1229                synchronized (ActivityManagerService.this) {
1230                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1231                    ProcessRecord proc = (ProcessRecord)data.get("app");
1232                    if (proc != null && proc.anrDialog != null) {
1233                        Slog.e(TAG, "App already has anr dialog: " + proc);
1234                        return;
1235                    }
1236
1237                    Intent intent = new Intent("android.intent.action.ANR");
1238                    if (!mProcessesReady) {
1239                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1240                                | Intent.FLAG_RECEIVER_FOREGROUND);
1241                    }
1242                    broadcastIntentLocked(null, null, intent,
1243                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1244                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1245
1246                    if (mShowDialogs) {
1247                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1248                                mContext, proc, (ActivityRecord)data.get("activity"),
1249                                msg.arg1 != 0);
1250                        d.show();
1251                        proc.anrDialog = d;
1252                    } else {
1253                        // Just kill the app if there is no dialog to be shown.
1254                        killAppAtUsersRequest(proc, null);
1255                    }
1256                }
1257
1258                ensureBootCompleted();
1259            } break;
1260            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1261                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1262                synchronized (ActivityManagerService.this) {
1263                    ProcessRecord proc = (ProcessRecord) data.get("app");
1264                    if (proc == null) {
1265                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1266                        break;
1267                    }
1268                    if (proc.crashDialog != null) {
1269                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1270                        return;
1271                    }
1272                    AppErrorResult res = (AppErrorResult) data.get("result");
1273                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1274                        Dialog d = new StrictModeViolationDialog(mContext,
1275                                ActivityManagerService.this, res, proc);
1276                        d.show();
1277                        proc.crashDialog = d;
1278                    } else {
1279                        // The device is asleep, so just pretend that the user
1280                        // saw a crash dialog and hit "force quit".
1281                        res.set(0);
1282                    }
1283                }
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_FACTORY_ERROR_MSG: {
1287                Dialog d = new FactoryErrorDialog(
1288                    mContext, msg.getData().getCharSequence("msg"));
1289                d.show();
1290                ensureBootCompleted();
1291            } break;
1292            case UPDATE_CONFIGURATION_MSG: {
1293                final ContentResolver resolver = mContext.getContentResolver();
1294                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1295            } break;
1296            case GC_BACKGROUND_PROCESSES_MSG: {
1297                synchronized (ActivityManagerService.this) {
1298                    performAppGcsIfAppropriateLocked();
1299                }
1300            } break;
1301            case WAIT_FOR_DEBUGGER_MSG: {
1302                synchronized (ActivityManagerService.this) {
1303                    ProcessRecord app = (ProcessRecord)msg.obj;
1304                    if (msg.arg1 != 0) {
1305                        if (!app.waitedForDebugger) {
1306                            Dialog d = new AppWaitingForDebuggerDialog(
1307                                    ActivityManagerService.this,
1308                                    mContext, app);
1309                            app.waitDialog = d;
1310                            app.waitedForDebugger = true;
1311                            d.show();
1312                        }
1313                    } else {
1314                        if (app.waitDialog != null) {
1315                            app.waitDialog.dismiss();
1316                            app.waitDialog = null;
1317                        }
1318                    }
1319                }
1320            } break;
1321            case SERVICE_TIMEOUT_MSG: {
1322                if (mDidDexOpt) {
1323                    mDidDexOpt = false;
1324                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1325                    nmsg.obj = msg.obj;
1326                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1327                    return;
1328                }
1329                mServices.serviceTimeout((ProcessRecord)msg.obj);
1330            } break;
1331            case UPDATE_TIME_ZONE: {
1332                synchronized (ActivityManagerService.this) {
1333                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1334                        ProcessRecord r = mLruProcesses.get(i);
1335                        if (r.thread != null) {
1336                            try {
1337                                r.thread.updateTimeZone();
1338                            } catch (RemoteException ex) {
1339                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1340                            }
1341                        }
1342                    }
1343                }
1344            } break;
1345            case CLEAR_DNS_CACHE_MSG: {
1346                synchronized (ActivityManagerService.this) {
1347                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1348                        ProcessRecord r = mLruProcesses.get(i);
1349                        if (r.thread != null) {
1350                            try {
1351                                r.thread.clearDnsCache();
1352                            } catch (RemoteException ex) {
1353                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1354                            }
1355                        }
1356                    }
1357                }
1358            } break;
1359            case UPDATE_HTTP_PROXY_MSG: {
1360                ProxyInfo proxy = (ProxyInfo)msg.obj;
1361                String host = "";
1362                String port = "";
1363                String exclList = "";
1364                Uri pacFileUrl = Uri.EMPTY;
1365                if (proxy != null) {
1366                    host = proxy.getHost();
1367                    port = Integer.toString(proxy.getPort());
1368                    exclList = proxy.getExclusionListAsString();
1369                    pacFileUrl = proxy.getPacFileUrl();
1370                }
1371                synchronized (ActivityManagerService.this) {
1372                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1373                        ProcessRecord r = mLruProcesses.get(i);
1374                        if (r.thread != null) {
1375                            try {
1376                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1377                            } catch (RemoteException ex) {
1378                                Slog.w(TAG, "Failed to update http proxy for: " +
1379                                        r.info.processName);
1380                            }
1381                        }
1382                    }
1383                }
1384            } break;
1385            case SHOW_UID_ERROR_MSG: {
1386                String title = "System UIDs Inconsistent";
1387                String text = "UIDs on the system are inconsistent, you need to wipe your"
1388                        + " data partition or your device will be unstable.";
1389                Log.e(TAG, title + ": " + text);
1390                if (mShowDialogs) {
1391                    // XXX This is a temporary dialog, no need to localize.
1392                    AlertDialog d = new BaseErrorDialog(mContext);
1393                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1394                    d.setCancelable(false);
1395                    d.setTitle(title);
1396                    d.setMessage(text);
1397                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1398                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1399                    mUidAlert = d;
1400                    d.show();
1401                }
1402            } break;
1403            case IM_FEELING_LUCKY_MSG: {
1404                if (mUidAlert != null) {
1405                    mUidAlert.dismiss();
1406                    mUidAlert = null;
1407                }
1408            } break;
1409            case PROC_START_TIMEOUT_MSG: {
1410                if (mDidDexOpt) {
1411                    mDidDexOpt = false;
1412                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1413                    nmsg.obj = msg.obj;
1414                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1415                    return;
1416                }
1417                ProcessRecord app = (ProcessRecord)msg.obj;
1418                synchronized (ActivityManagerService.this) {
1419                    processStartTimedOutLocked(app);
1420                }
1421            } break;
1422            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    doPendingActivityLaunchesLocked(true);
1425                }
1426            } break;
1427            case KILL_APPLICATION_MSG: {
1428                synchronized (ActivityManagerService.this) {
1429                    int appid = msg.arg1;
1430                    boolean restart = (msg.arg2 == 1);
1431                    Bundle bundle = (Bundle)msg.obj;
1432                    String pkg = bundle.getString("pkg");
1433                    String reason = bundle.getString("reason");
1434                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1435                            false, UserHandle.USER_ALL, reason);
1436                }
1437            } break;
1438            case FINALIZE_PENDING_INTENT_MSG: {
1439                ((PendingIntentRecord)msg.obj).completeFinalize();
1440            } break;
1441            case POST_HEAVY_NOTIFICATION_MSG: {
1442                INotificationManager inm = NotificationManager.getService();
1443                if (inm == null) {
1444                    return;
1445                }
1446
1447                ActivityRecord root = (ActivityRecord)msg.obj;
1448                ProcessRecord process = root.app;
1449                if (process == null) {
1450                    return;
1451                }
1452
1453                try {
1454                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1455                    String text = mContext.getString(R.string.heavy_weight_notification,
1456                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1457                    Notification notification = new Notification();
1458                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1459                    notification.when = 0;
1460                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1461                    notification.tickerText = text;
1462                    notification.defaults = 0; // please be quiet
1463                    notification.sound = null;
1464                    notification.vibrate = null;
1465                    notification.setLatestEventInfo(context, text,
1466                            mContext.getText(R.string.heavy_weight_notification_detail),
1467                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1468                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1469                                    new UserHandle(root.userId)));
1470
1471                    try {
1472                        int[] outId = new int[1];
1473                        inm.enqueueNotificationWithTag("android", "android", null,
1474                                R.string.heavy_weight_notification,
1475                                notification, outId, root.userId);
1476                    } catch (RuntimeException e) {
1477                        Slog.w(ActivityManagerService.TAG,
1478                                "Error showing notification for heavy-weight app", e);
1479                    } catch (RemoteException e) {
1480                    }
1481                } catch (NameNotFoundException e) {
1482                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1483                }
1484            } break;
1485            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1486                INotificationManager inm = NotificationManager.getService();
1487                if (inm == null) {
1488                    return;
1489                }
1490                try {
1491                    inm.cancelNotificationWithTag("android", null,
1492                            R.string.heavy_weight_notification,  msg.arg1);
1493                } catch (RuntimeException e) {
1494                    Slog.w(ActivityManagerService.TAG,
1495                            "Error canceling notification for service", e);
1496                } catch (RemoteException e) {
1497                }
1498            } break;
1499            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1500                synchronized (ActivityManagerService.this) {
1501                    checkExcessivePowerUsageLocked(true);
1502                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1503                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1504                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1505                }
1506            } break;
1507            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1508                synchronized (ActivityManagerService.this) {
1509                    ActivityRecord ar = (ActivityRecord)msg.obj;
1510                    if (mCompatModeDialog != null) {
1511                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1512                                ar.info.applicationInfo.packageName)) {
1513                            return;
1514                        }
1515                        mCompatModeDialog.dismiss();
1516                        mCompatModeDialog = null;
1517                    }
1518                    if (ar != null && false) {
1519                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1520                                ar.packageName)) {
1521                            int mode = mCompatModePackages.computeCompatModeLocked(
1522                                    ar.info.applicationInfo);
1523                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1524                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1525                                mCompatModeDialog = new CompatModeDialog(
1526                                        ActivityManagerService.this, mContext,
1527                                        ar.info.applicationInfo);
1528                                mCompatModeDialog.show();
1529                            }
1530                        }
1531                    }
1532                }
1533                break;
1534            }
1535            case DISPATCH_PROCESSES_CHANGED: {
1536                dispatchProcessesChanged();
1537                break;
1538            }
1539            case DISPATCH_PROCESS_DIED: {
1540                final int pid = msg.arg1;
1541                final int uid = msg.arg2;
1542                dispatchProcessDied(pid, uid);
1543                break;
1544            }
1545            case REPORT_MEM_USAGE_MSG: {
1546                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1547                Thread thread = new Thread() {
1548                    @Override public void run() {
1549                        final SparseArray<ProcessMemInfo> infoMap
1550                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1551                        for (int i=0, N=memInfos.size(); i<N; i++) {
1552                            ProcessMemInfo mi = memInfos.get(i);
1553                            infoMap.put(mi.pid, mi);
1554                        }
1555                        updateCpuStatsNow();
1556                        synchronized (mProcessCpuThread) {
1557                            final int N = mProcessCpuTracker.countStats();
1558                            for (int i=0; i<N; i++) {
1559                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1560                                if (st.vsize > 0) {
1561                                    long pss = Debug.getPss(st.pid, null);
1562                                    if (pss > 0) {
1563                                        if (infoMap.indexOfKey(st.pid) < 0) {
1564                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1565                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1566                                            mi.pss = pss;
1567                                            memInfos.add(mi);
1568                                        }
1569                                    }
1570                                }
1571                            }
1572                        }
1573
1574                        long totalPss = 0;
1575                        for (int i=0, N=memInfos.size(); i<N; i++) {
1576                            ProcessMemInfo mi = memInfos.get(i);
1577                            if (mi.pss == 0) {
1578                                mi.pss = Debug.getPss(mi.pid, null);
1579                            }
1580                            totalPss += mi.pss;
1581                        }
1582                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1583                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1584                                if (lhs.oomAdj != rhs.oomAdj) {
1585                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1586                                }
1587                                if (lhs.pss != rhs.pss) {
1588                                    return lhs.pss < rhs.pss ? 1 : -1;
1589                                }
1590                                return 0;
1591                            }
1592                        });
1593
1594                        StringBuilder tag = new StringBuilder(128);
1595                        StringBuilder stack = new StringBuilder(128);
1596                        tag.append("Low on memory -- ");
1597                        appendMemBucket(tag, totalPss, "total", false);
1598                        appendMemBucket(stack, totalPss, "total", true);
1599
1600                        StringBuilder logBuilder = new StringBuilder(1024);
1601                        logBuilder.append("Low on memory:\n");
1602
1603                        boolean firstLine = true;
1604                        int lastOomAdj = Integer.MIN_VALUE;
1605                        for (int i=0, N=memInfos.size(); i<N; i++) {
1606                            ProcessMemInfo mi = memInfos.get(i);
1607
1608                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1609                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1610                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1611                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1612                                if (lastOomAdj != mi.oomAdj) {
1613                                    lastOomAdj = mi.oomAdj;
1614                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1615                                        tag.append(" / ");
1616                                    }
1617                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1618                                        if (firstLine) {
1619                                            stack.append(":");
1620                                            firstLine = false;
1621                                        }
1622                                        stack.append("\n\t at ");
1623                                    } else {
1624                                        stack.append("$");
1625                                    }
1626                                } else {
1627                                    tag.append(" ");
1628                                    stack.append("$");
1629                                }
1630                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1631                                    appendMemBucket(tag, mi.pss, mi.name, false);
1632                                }
1633                                appendMemBucket(stack, mi.pss, mi.name, true);
1634                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1635                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1636                                    stack.append("(");
1637                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1638                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1639                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1640                                            stack.append(":");
1641                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1642                                        }
1643                                    }
1644                                    stack.append(")");
1645                                }
1646                            }
1647
1648                            logBuilder.append("  ");
1649                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1650                            logBuilder.append(' ');
1651                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1652                            logBuilder.append(' ');
1653                            ProcessList.appendRamKb(logBuilder, mi.pss);
1654                            logBuilder.append(" kB: ");
1655                            logBuilder.append(mi.name);
1656                            logBuilder.append(" (");
1657                            logBuilder.append(mi.pid);
1658                            logBuilder.append(") ");
1659                            logBuilder.append(mi.adjType);
1660                            logBuilder.append('\n');
1661                            if (mi.adjReason != null) {
1662                                logBuilder.append("                      ");
1663                                logBuilder.append(mi.adjReason);
1664                                logBuilder.append('\n');
1665                            }
1666                        }
1667
1668                        logBuilder.append("           ");
1669                        ProcessList.appendRamKb(logBuilder, totalPss);
1670                        logBuilder.append(" kB: TOTAL\n");
1671
1672                        long[] infos = new long[Debug.MEMINFO_COUNT];
1673                        Debug.getMemInfo(infos);
1674                        logBuilder.append("  MemInfo: ");
1675                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1676                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1677                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1678                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1679                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1680                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1681                            logBuilder.append("  ZRAM: ");
1682                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1683                            logBuilder.append(" kB RAM, ");
1684                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1685                            logBuilder.append(" kB swap total, ");
1686                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1687                            logBuilder.append(" kB swap free\n");
1688                        }
1689                        Slog.i(TAG, logBuilder.toString());
1690
1691                        StringBuilder dropBuilder = new StringBuilder(1024);
1692                        /*
1693                        StringWriter oomSw = new StringWriter();
1694                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1695                        StringWriter catSw = new StringWriter();
1696                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1697                        String[] emptyArgs = new String[] { };
1698                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1699                        oomPw.flush();
1700                        String oomString = oomSw.toString();
1701                        */
1702                        dropBuilder.append(stack);
1703                        dropBuilder.append('\n');
1704                        dropBuilder.append('\n');
1705                        dropBuilder.append(logBuilder);
1706                        dropBuilder.append('\n');
1707                        /*
1708                        dropBuilder.append(oomString);
1709                        dropBuilder.append('\n');
1710                        */
1711                        StringWriter catSw = new StringWriter();
1712                        synchronized (ActivityManagerService.this) {
1713                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1714                            String[] emptyArgs = new String[] { };
1715                            catPw.println();
1716                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1717                            catPw.println();
1718                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1719                                    false, false, null);
1720                            catPw.println();
1721                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1722                            catPw.flush();
1723                        }
1724                        dropBuilder.append(catSw.toString());
1725                        addErrorToDropBox("lowmem", null, "system_server", null,
1726                                null, tag.toString(), dropBuilder.toString(), null, null);
1727                        //Slog.i(TAG, "Sent to dropbox:");
1728                        //Slog.i(TAG, dropBuilder.toString());
1729                        synchronized (ActivityManagerService.this) {
1730                            long now = SystemClock.uptimeMillis();
1731                            if (mLastMemUsageReportTime < now) {
1732                                mLastMemUsageReportTime = now;
1733                            }
1734                        }
1735                    }
1736                };
1737                thread.start();
1738                break;
1739            }
1740            case REPORT_USER_SWITCH_MSG: {
1741                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1742                break;
1743            }
1744            case CONTINUE_USER_SWITCH_MSG: {
1745                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1746                break;
1747            }
1748            case USER_SWITCH_TIMEOUT_MSG: {
1749                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1750                break;
1751            }
1752            case IMMERSIVE_MODE_LOCK_MSG: {
1753                final boolean nextState = (msg.arg1 != 0);
1754                if (mUpdateLock.isHeld() != nextState) {
1755                    if (DEBUG_IMMERSIVE) {
1756                        final ActivityRecord r = (ActivityRecord) msg.obj;
1757                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1758                    }
1759                    if (nextState) {
1760                        mUpdateLock.acquire();
1761                    } else {
1762                        mUpdateLock.release();
1763                    }
1764                }
1765                break;
1766            }
1767            case PERSIST_URI_GRANTS_MSG: {
1768                writeGrantedUriPermissions();
1769                break;
1770            }
1771            case REQUEST_ALL_PSS_MSG: {
1772                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1773                break;
1774            }
1775            case START_PROFILES_MSG: {
1776                synchronized (ActivityManagerService.this) {
1777                    startProfilesLocked();
1778                }
1779                break;
1780            }
1781            case UPDATE_TIME: {
1782                synchronized (ActivityManagerService.this) {
1783                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1784                        ProcessRecord r = mLruProcesses.get(i);
1785                        if (r.thread != null) {
1786                            try {
1787                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1788                            } catch (RemoteException ex) {
1789                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1790                            }
1791                        }
1792                    }
1793                }
1794                break;
1795            }
1796            case SYSTEM_USER_START_MSG: {
1797                mSystemServiceManager.startUser(msg.arg1);
1798                break;
1799            }
1800            case SYSTEM_USER_CURRENT_MSG: {
1801                mSystemServiceManager.switchUser(msg.arg1);
1802                break;
1803            }
1804            }
1805        }
1806    };
1807
1808    static final int COLLECT_PSS_BG_MSG = 1;
1809
1810    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1811        @Override
1812        public void handleMessage(Message msg) {
1813            switch (msg.what) {
1814            case COLLECT_PSS_BG_MSG: {
1815                long start = SystemClock.uptimeMillis();
1816                MemInfoReader memInfo = null;
1817                synchronized (ActivityManagerService.this) {
1818                    if (mFullPssPending) {
1819                        mFullPssPending = false;
1820                        memInfo = new MemInfoReader();
1821                    }
1822                }
1823                if (memInfo != null) {
1824                    updateCpuStatsNow();
1825                    long nativeTotalPss = 0;
1826                    synchronized (mProcessCpuThread) {
1827                        final int N = mProcessCpuTracker.countStats();
1828                        for (int j=0; j<N; j++) {
1829                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1830                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1831                                // This is definitely an application process; skip it.
1832                                continue;
1833                            }
1834                            synchronized (mPidsSelfLocked) {
1835                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1836                                    // This is one of our own processes; skip it.
1837                                    continue;
1838                                }
1839                            }
1840                            nativeTotalPss += Debug.getPss(st.pid, null);
1841                        }
1842                    }
1843                    memInfo.readMemInfo();
1844                    synchronized (this) {
1845                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1846                                + (SystemClock.uptimeMillis()-start) + "ms");
1847                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1848                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1849                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1850                                        +memInfo.getSlabSizeKb(),
1851                                nativeTotalPss);
1852                    }
1853                }
1854
1855                int i=0, num=0;
1856                long[] tmp = new long[1];
1857                do {
1858                    ProcessRecord proc;
1859                    int procState;
1860                    int pid;
1861                    synchronized (ActivityManagerService.this) {
1862                        if (i >= mPendingPssProcesses.size()) {
1863                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1864                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1865                            mPendingPssProcesses.clear();
1866                            return;
1867                        }
1868                        proc = mPendingPssProcesses.get(i);
1869                        procState = proc.pssProcState;
1870                        if (proc.thread != null && procState == proc.setProcState) {
1871                            pid = proc.pid;
1872                        } else {
1873                            proc = null;
1874                            pid = 0;
1875                        }
1876                        i++;
1877                    }
1878                    if (proc != null) {
1879                        long pss = Debug.getPss(pid, tmp);
1880                        synchronized (ActivityManagerService.this) {
1881                            if (proc.thread != null && proc.setProcState == procState
1882                                    && proc.pid == pid) {
1883                                num++;
1884                                proc.lastPssTime = SystemClock.uptimeMillis();
1885                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1886                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1887                                        + ": " + pss + " lastPss=" + proc.lastPss
1888                                        + " state=" + ProcessList.makeProcStateString(procState));
1889                                if (proc.initialIdlePss == 0) {
1890                                    proc.initialIdlePss = pss;
1891                                }
1892                                proc.lastPss = pss;
1893                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1894                                    proc.lastCachedPss = pss;
1895                                }
1896                            }
1897                        }
1898                    }
1899                } while (true);
1900            }
1901            }
1902        }
1903    };
1904
1905    /**
1906     * Monitor for package changes and update our internal state.
1907     */
1908    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1909        @Override
1910        public void onPackageRemoved(String packageName, int uid) {
1911            // Remove all tasks with activities in the specified package from the list of recent tasks
1912            synchronized (ActivityManagerService.this) {
1913                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1914                    TaskRecord tr = mRecentTasks.get(i);
1915                    ComponentName cn = tr.intent.getComponent();
1916                    if (cn != null && cn.getPackageName().equals(packageName)) {
1917                        // If the package name matches, remove the task and kill the process
1918                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1919                    }
1920                }
1921            }
1922        }
1923
1924        @Override
1925        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1926            onPackageModified(packageName);
1927            return true;
1928        }
1929
1930        @Override
1931        public void onPackageModified(String packageName) {
1932            final PackageManager pm = mContext.getPackageManager();
1933            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1934                    new ArrayList<Pair<Intent, Integer>>();
1935            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1936            // Copy the list of recent tasks so that we don't hold onto the lock on
1937            // ActivityManagerService for long periods while checking if components exist.
1938            synchronized (ActivityManagerService.this) {
1939                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1940                    TaskRecord tr = mRecentTasks.get(i);
1941                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1942                }
1943            }
1944            // Check the recent tasks and filter out all tasks with components that no longer exist.
1945            Intent tmpI = new Intent();
1946            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1947                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1948                ComponentName cn = p.first.getComponent();
1949                if (cn != null && cn.getPackageName().equals(packageName)) {
1950                    try {
1951                        // Add the task to the list to remove if the component no longer exists
1952                        tmpI.setComponent(cn);
1953                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1954                            tasksToRemove.add(p.second);
1955                        }
1956                    } catch (Exception e) {}
1957                }
1958            }
1959            // Prune all the tasks with removed components from the list of recent tasks
1960            synchronized (ActivityManagerService.this) {
1961                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1962                    // Remove the task but don't kill the process (since other components in that
1963                    // package may still be running and in the background)
1964                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1965                }
1966            }
1967        }
1968
1969        @Override
1970        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1971            // Force stop the specified packages
1972            if (packages != null) {
1973                for (String pkg : packages) {
1974                    synchronized (ActivityManagerService.this) {
1975                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1976                                "finished booting")) {
1977                            return true;
1978                        }
1979                    }
1980                }
1981            }
1982            return false;
1983        }
1984    };
1985
1986    public void setSystemProcess() {
1987        try {
1988            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1989            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1990            ServiceManager.addService("meminfo", new MemBinder(this));
1991            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1992            ServiceManager.addService("dbinfo", new DbBinder(this));
1993            if (MONITOR_CPU_USAGE) {
1994                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1995            }
1996            ServiceManager.addService("permission", new PermissionController(this));
1997
1998            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1999                    "android", STOCK_PM_FLAGS);
2000            mSystemThread.installSystemApplicationInfo(info);
2001
2002            synchronized (this) {
2003                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2004                app.persistent = true;
2005                app.pid = MY_PID;
2006                app.maxAdj = ProcessList.SYSTEM_ADJ;
2007                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2008                mProcessNames.put(app.processName, app.uid, app);
2009                synchronized (mPidsSelfLocked) {
2010                    mPidsSelfLocked.put(app.pid, app);
2011                }
2012                updateLruProcessLocked(app, false, null);
2013                updateOomAdjLocked();
2014            }
2015        } catch (PackageManager.NameNotFoundException e) {
2016            throw new RuntimeException(
2017                    "Unable to find android system package", e);
2018        }
2019    }
2020
2021    public void setWindowManager(WindowManagerService wm) {
2022        mWindowManager = wm;
2023        mStackSupervisor.setWindowManager(wm);
2024    }
2025
2026    public void startObservingNativeCrashes() {
2027        final NativeCrashListener ncl = new NativeCrashListener(this);
2028        ncl.start();
2029    }
2030
2031    public IAppOpsService getAppOpsService() {
2032        return mAppOpsService;
2033    }
2034
2035    static class MemBinder extends Binder {
2036        ActivityManagerService mActivityManagerService;
2037        MemBinder(ActivityManagerService activityManagerService) {
2038            mActivityManagerService = activityManagerService;
2039        }
2040
2041        @Override
2042        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2043            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2044                    != PackageManager.PERMISSION_GRANTED) {
2045                pw.println("Permission Denial: can't dump meminfo from from pid="
2046                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2047                        + " without permission " + android.Manifest.permission.DUMP);
2048                return;
2049            }
2050
2051            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2052        }
2053    }
2054
2055    static class GraphicsBinder extends Binder {
2056        ActivityManagerService mActivityManagerService;
2057        GraphicsBinder(ActivityManagerService activityManagerService) {
2058            mActivityManagerService = activityManagerService;
2059        }
2060
2061        @Override
2062        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2063            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2064                    != PackageManager.PERMISSION_GRANTED) {
2065                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2066                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2067                        + " without permission " + android.Manifest.permission.DUMP);
2068                return;
2069            }
2070
2071            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2072        }
2073    }
2074
2075    static class DbBinder extends Binder {
2076        ActivityManagerService mActivityManagerService;
2077        DbBinder(ActivityManagerService activityManagerService) {
2078            mActivityManagerService = activityManagerService;
2079        }
2080
2081        @Override
2082        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2083            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2084                    != PackageManager.PERMISSION_GRANTED) {
2085                pw.println("Permission Denial: can't dump dbinfo from from pid="
2086                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2087                        + " without permission " + android.Manifest.permission.DUMP);
2088                return;
2089            }
2090
2091            mActivityManagerService.dumpDbInfo(fd, pw, args);
2092        }
2093    }
2094
2095    static class CpuBinder extends Binder {
2096        ActivityManagerService mActivityManagerService;
2097        CpuBinder(ActivityManagerService activityManagerService) {
2098            mActivityManagerService = activityManagerService;
2099        }
2100
2101        @Override
2102        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2103            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2104                    != PackageManager.PERMISSION_GRANTED) {
2105                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2106                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2107                        + " without permission " + android.Manifest.permission.DUMP);
2108                return;
2109            }
2110
2111            synchronized (mActivityManagerService.mProcessCpuThread) {
2112                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2113                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2114                        SystemClock.uptimeMillis()));
2115            }
2116        }
2117    }
2118
2119    public static final class Lifecycle extends SystemService {
2120        private final ActivityManagerService mService;
2121
2122        public Lifecycle(Context context) {
2123            super(context);
2124            mService = new ActivityManagerService(context);
2125        }
2126
2127        @Override
2128        public void onStart() {
2129            mService.start();
2130        }
2131
2132        public ActivityManagerService getService() {
2133            return mService;
2134        }
2135    }
2136
2137    // Note: This method is invoked on the main thread but may need to attach various
2138    // handlers to other threads.  So take care to be explicit about the looper.
2139    public ActivityManagerService(Context systemContext) {
2140        mContext = systemContext;
2141        mFactoryTest = FactoryTest.getMode();
2142        mSystemThread = ActivityThread.currentActivityThread();
2143
2144        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2145
2146        mHandlerThread = new ServiceThread(TAG,
2147                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2148        mHandlerThread.start();
2149        mHandler = new MainHandler(mHandlerThread.getLooper());
2150
2151        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2152                "foreground", BROADCAST_FG_TIMEOUT, false);
2153        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2154                "background", BROADCAST_BG_TIMEOUT, true);
2155        mBroadcastQueues[0] = mFgBroadcastQueue;
2156        mBroadcastQueues[1] = mBgBroadcastQueue;
2157
2158        mServices = new ActiveServices(this);
2159        mProviderMap = new ProviderMap(this);
2160
2161        // TODO: Move creation of battery stats service outside of activity manager service.
2162        File dataDir = Environment.getDataDirectory();
2163        File systemDir = new File(dataDir, "system");
2164        systemDir.mkdirs();
2165        mBatteryStatsService = new BatteryStatsService(new File(
2166                systemDir, "batterystats.bin").toString(), mHandler);
2167        mBatteryStatsService.getActiveStatistics().readLocked();
2168        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2169        mOnBattery = DEBUG_POWER ? true
2170                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2171        mBatteryStatsService.getActiveStatistics().setCallback(this);
2172
2173        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2174
2175        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2176        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2177
2178        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2179
2180        // User 0 is the first and only user that runs at boot.
2181        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2182        mUserLru.add(Integer.valueOf(0));
2183        updateStartedUserArrayLocked();
2184
2185        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2186            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2187
2188        mConfiguration.setToDefaults();
2189        mConfiguration.setLocale(Locale.getDefault());
2190
2191        mConfigurationSeq = mConfiguration.seq = 1;
2192        mProcessCpuTracker.init();
2193
2194        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2195        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2196        mStackSupervisor = new ActivityStackSupervisor(this);
2197        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2198
2199        mProcessCpuThread = new Thread("CpuTracker") {
2200            @Override
2201            public void run() {
2202                while (true) {
2203                    try {
2204                        try {
2205                            synchronized(this) {
2206                                final long now = SystemClock.uptimeMillis();
2207                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2208                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2209                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2210                                //        + ", write delay=" + nextWriteDelay);
2211                                if (nextWriteDelay < nextCpuDelay) {
2212                                    nextCpuDelay = nextWriteDelay;
2213                                }
2214                                if (nextCpuDelay > 0) {
2215                                    mProcessCpuMutexFree.set(true);
2216                                    this.wait(nextCpuDelay);
2217                                }
2218                            }
2219                        } catch (InterruptedException e) {
2220                        }
2221                        updateCpuStatsNow();
2222                    } catch (Exception e) {
2223                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2224                    }
2225                }
2226            }
2227        };
2228
2229        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2230
2231        Watchdog.getInstance().addMonitor(this);
2232        Watchdog.getInstance().addThread(mHandler);
2233    }
2234
2235    public void setSystemServiceManager(SystemServiceManager mgr) {
2236        mSystemServiceManager = mgr;
2237    }
2238
2239    private void start() {
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            handleAppDiedLocked(app, true, true);
2832        }
2833
2834        String hostingNameStr = hostingName != null
2835                ? hostingName.flattenToShortString() : null;
2836
2837        if (!isolated) {
2838            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2839                // If we are in the background, then check to see if this process
2840                // is bad.  If so, we will just silently fail.
2841                if (mBadProcesses.get(info.processName, info.uid) != null) {
2842                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2843                            + "/" + info.processName);
2844                    return null;
2845                }
2846            } else {
2847                // When the user is explicitly starting a process, then clear its
2848                // crash count so that we won't make it bad until they see at
2849                // least one crash dialog again, and make the process good again
2850                // if it had been bad.
2851                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2852                        + "/" + info.processName);
2853                mProcessCrashTimes.remove(info.processName, info.uid);
2854                if (mBadProcesses.get(info.processName, info.uid) != null) {
2855                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2856                            UserHandle.getUserId(info.uid), info.uid,
2857                            info.processName);
2858                    mBadProcesses.remove(info.processName, info.uid);
2859                    if (app != null) {
2860                        app.bad = false;
2861                    }
2862                }
2863            }
2864        }
2865
2866        if (app == null) {
2867            app = newProcessRecordLocked(info, processName, isolated);
2868            if (app == null) {
2869                Slog.w(TAG, "Failed making new process record for "
2870                        + processName + "/" + info.uid + " isolated=" + isolated);
2871                return null;
2872            }
2873            mProcessNames.put(processName, app.uid, app);
2874            if (isolated) {
2875                mIsolatedProcesses.put(app.uid, app);
2876            }
2877        } else {
2878            // If this is a new package in the process, add the package to the list
2879            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2880        }
2881
2882        // If the system is not ready yet, then hold off on starting this
2883        // process until it is.
2884        if (!mProcessesReady
2885                && !isAllowedWhileBooting(info)
2886                && !allowWhileBooting) {
2887            if (!mProcessesOnHold.contains(app)) {
2888                mProcessesOnHold.add(app);
2889            }
2890            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2891            return app;
2892        }
2893
2894        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2895        return (app.pid != 0) ? app : null;
2896    }
2897
2898    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2899        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2900    }
2901
2902    private final void startProcessLocked(ProcessRecord app,
2903            String hostingType, String hostingNameStr, String abiOverride) {
2904        if (app.pid > 0 && app.pid != MY_PID) {
2905            synchronized (mPidsSelfLocked) {
2906                mPidsSelfLocked.remove(app.pid);
2907                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2908            }
2909            app.setPid(0);
2910        }
2911
2912        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2913                "startProcessLocked removing on hold: " + app);
2914        mProcessesOnHold.remove(app);
2915
2916        updateCpuStats();
2917
2918        try {
2919            int uid = app.uid;
2920
2921            int[] gids = null;
2922            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2923            if (!app.isolated) {
2924                int[] permGids = null;
2925                try {
2926                    final PackageManager pm = mContext.getPackageManager();
2927                    permGids = pm.getPackageGids(app.info.packageName);
2928
2929                    if (Environment.isExternalStorageEmulated()) {
2930                        if (pm.checkPermission(
2931                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2932                                app.info.packageName) == PERMISSION_GRANTED) {
2933                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2934                        } else {
2935                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2936                        }
2937                    }
2938                } catch (PackageManager.NameNotFoundException e) {
2939                    Slog.w(TAG, "Unable to retrieve gids", e);
2940                }
2941
2942                /*
2943                 * Add shared application and profile GIDs so applications can share some
2944                 * resources like shared libraries and access user-wide resources
2945                 */
2946                if (permGids == null) {
2947                    gids = new int[2];
2948                } else {
2949                    gids = new int[permGids.length + 2];
2950                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2951                }
2952                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2953                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2954            }
2955            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2956                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2957                        && mTopComponent != null
2958                        && app.processName.equals(mTopComponent.getPackageName())) {
2959                    uid = 0;
2960                }
2961                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2962                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2963                    uid = 0;
2964                }
2965            }
2966            int debugFlags = 0;
2967            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2968                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2969                // Also turn on CheckJNI for debuggable apps. It's quite
2970                // awkward to turn on otherwise.
2971                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2972            }
2973            // Run the app in safe mode if its manifest requests so or the
2974            // system is booted in safe mode.
2975            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2976                mSafeMode == true) {
2977                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2978            }
2979            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2980                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2981            }
2982            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2983                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2984            }
2985            if ("1".equals(SystemProperties.get("debug.assert"))) {
2986                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2987            }
2988
2989            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2990            if (requiredAbi == null) {
2991                requiredAbi = Build.SUPPORTED_ABIS[0];
2992            }
2993
2994            // Start the process.  It will either succeed and return a result containing
2995            // the PID of the new process, or else throw a RuntimeException.
2996            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2997                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2998                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2999
3000            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
3001            synchronized (bs) {
3002                if (bs.isOnBattery()) {
3003                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
3004                }
3005            }
3006
3007            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3008                    UserHandle.getUserId(uid), startResult.pid, uid,
3009                    app.processName, hostingType,
3010                    hostingNameStr != null ? hostingNameStr : "");
3011
3012            if (app.persistent) {
3013                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3014            }
3015
3016            StringBuilder buf = mStringBuilder;
3017            buf.setLength(0);
3018            buf.append("Start proc ");
3019            buf.append(app.processName);
3020            buf.append(" for ");
3021            buf.append(hostingType);
3022            if (hostingNameStr != null) {
3023                buf.append(" ");
3024                buf.append(hostingNameStr);
3025            }
3026            buf.append(": pid=");
3027            buf.append(startResult.pid);
3028            buf.append(" uid=");
3029            buf.append(uid);
3030            buf.append(" gids={");
3031            if (gids != null) {
3032                for (int gi=0; gi<gids.length; gi++) {
3033                    if (gi != 0) buf.append(", ");
3034                    buf.append(gids[gi]);
3035
3036                }
3037            }
3038            buf.append("}");
3039            if (requiredAbi != null) {
3040                buf.append(" abi=");
3041                buf.append(requiredAbi);
3042            }
3043            Slog.i(TAG, buf.toString());
3044            app.setPid(startResult.pid);
3045            app.usingWrapper = startResult.usingWrapper;
3046            app.removed = false;
3047            app.killedByAm = false;
3048            synchronized (mPidsSelfLocked) {
3049                this.mPidsSelfLocked.put(startResult.pid, app);
3050                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3051                msg.obj = app;
3052                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3053                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3054            }
3055            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3056                    app.processName, app.info.uid);
3057            if (app.isolated) {
3058                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3059            }
3060        } catch (RuntimeException e) {
3061            // XXX do better error recovery.
3062            app.setPid(0);
3063            Slog.e(TAG, "Failure starting process " + app.processName, e);
3064        }
3065    }
3066
3067    void updateUsageStats(ActivityRecord component, boolean resumed) {
3068        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3069        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3070        if (resumed) {
3071            mUsageStatsService.noteResumeComponent(component.realActivity);
3072            synchronized (stats) {
3073                stats.noteActivityResumedLocked(component.app.uid);
3074            }
3075        } else {
3076            mUsageStatsService.notePauseComponent(component.realActivity);
3077            synchronized (stats) {
3078                stats.noteActivityPausedLocked(component.app.uid);
3079            }
3080        }
3081    }
3082
3083    Intent getHomeIntent() {
3084        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3085        intent.setComponent(mTopComponent);
3086        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3087            intent.addCategory(Intent.CATEGORY_HOME);
3088        }
3089        return intent;
3090    }
3091
3092    boolean startHomeActivityLocked(int userId) {
3093        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3094                && mTopAction == null) {
3095            // We are running in factory test mode, but unable to find
3096            // the factory test app, so just sit around displaying the
3097            // error message and don't try to start anything.
3098            return false;
3099        }
3100        Intent intent = getHomeIntent();
3101        ActivityInfo aInfo =
3102            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3103        if (aInfo != null) {
3104            intent.setComponent(new ComponentName(
3105                    aInfo.applicationInfo.packageName, aInfo.name));
3106            // Don't do this if the home app is currently being
3107            // instrumented.
3108            aInfo = new ActivityInfo(aInfo);
3109            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3110            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3111                    aInfo.applicationInfo.uid, true);
3112            if (app == null || app.instrumentationClass == null) {
3113                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3114                mStackSupervisor.startHomeActivity(intent, aInfo);
3115            }
3116        }
3117
3118        return true;
3119    }
3120
3121    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3122        ActivityInfo ai = null;
3123        ComponentName comp = intent.getComponent();
3124        try {
3125            if (comp != null) {
3126                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3127            } else {
3128                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3129                        intent,
3130                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3131                            flags, userId);
3132
3133                if (info != null) {
3134                    ai = info.activityInfo;
3135                }
3136            }
3137        } catch (RemoteException e) {
3138            // ignore
3139        }
3140
3141        return ai;
3142    }
3143
3144    /**
3145     * Starts the "new version setup screen" if appropriate.
3146     */
3147    void startSetupActivityLocked() {
3148        // Only do this once per boot.
3149        if (mCheckedForSetup) {
3150            return;
3151        }
3152
3153        // We will show this screen if the current one is a different
3154        // version than the last one shown, and we are not running in
3155        // low-level factory test mode.
3156        final ContentResolver resolver = mContext.getContentResolver();
3157        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3158                Settings.Global.getInt(resolver,
3159                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3160            mCheckedForSetup = true;
3161
3162            // See if we should be showing the platform update setup UI.
3163            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3164            List<ResolveInfo> ris = mContext.getPackageManager()
3165                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3166
3167            // We don't allow third party apps to replace this.
3168            ResolveInfo ri = null;
3169            for (int i=0; ris != null && i<ris.size(); i++) {
3170                if ((ris.get(i).activityInfo.applicationInfo.flags
3171                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3172                    ri = ris.get(i);
3173                    break;
3174                }
3175            }
3176
3177            if (ri != null) {
3178                String vers = ri.activityInfo.metaData != null
3179                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3180                        : null;
3181                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3182                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3183                            Intent.METADATA_SETUP_VERSION);
3184                }
3185                String lastVers = Settings.Secure.getString(
3186                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3187                if (vers != null && !vers.equals(lastVers)) {
3188                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3189                    intent.setComponent(new ComponentName(
3190                            ri.activityInfo.packageName, ri.activityInfo.name));
3191                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3192                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3193                }
3194            }
3195        }
3196    }
3197
3198    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3199        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3200    }
3201
3202    void enforceNotIsolatedCaller(String caller) {
3203        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3204            throw new SecurityException("Isolated process not allowed to call " + caller);
3205        }
3206    }
3207
3208    @Override
3209    public int getFrontActivityScreenCompatMode() {
3210        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3211        synchronized (this) {
3212            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3213        }
3214    }
3215
3216    @Override
3217    public void setFrontActivityScreenCompatMode(int mode) {
3218        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3219                "setFrontActivityScreenCompatMode");
3220        synchronized (this) {
3221            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3222        }
3223    }
3224
3225    @Override
3226    public int getPackageScreenCompatMode(String packageName) {
3227        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3228        synchronized (this) {
3229            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3230        }
3231    }
3232
3233    @Override
3234    public void setPackageScreenCompatMode(String packageName, int mode) {
3235        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3236                "setPackageScreenCompatMode");
3237        synchronized (this) {
3238            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3239        }
3240    }
3241
3242    @Override
3243    public boolean getPackageAskScreenCompat(String packageName) {
3244        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3245        synchronized (this) {
3246            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3247        }
3248    }
3249
3250    @Override
3251    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3252        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3253                "setPackageAskScreenCompat");
3254        synchronized (this) {
3255            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3256        }
3257    }
3258
3259    private void dispatchProcessesChanged() {
3260        int N;
3261        synchronized (this) {
3262            N = mPendingProcessChanges.size();
3263            if (mActiveProcessChanges.length < N) {
3264                mActiveProcessChanges = new ProcessChangeItem[N];
3265            }
3266            mPendingProcessChanges.toArray(mActiveProcessChanges);
3267            mAvailProcessChanges.addAll(mPendingProcessChanges);
3268            mPendingProcessChanges.clear();
3269            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3270        }
3271
3272        int i = mProcessObservers.beginBroadcast();
3273        while (i > 0) {
3274            i--;
3275            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3276            if (observer != null) {
3277                try {
3278                    for (int j=0; j<N; j++) {
3279                        ProcessChangeItem item = mActiveProcessChanges[j];
3280                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3281                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3282                                    + item.pid + " uid=" + item.uid + ": "
3283                                    + item.foregroundActivities);
3284                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3285                                    item.foregroundActivities);
3286                        }
3287                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3288                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3289                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3290                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3291                        }
3292                    }
3293                } catch (RemoteException e) {
3294                }
3295            }
3296        }
3297        mProcessObservers.finishBroadcast();
3298    }
3299
3300    private void dispatchProcessDied(int pid, int uid) {
3301        int i = mProcessObservers.beginBroadcast();
3302        while (i > 0) {
3303            i--;
3304            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3305            if (observer != null) {
3306                try {
3307                    observer.onProcessDied(pid, uid);
3308                } catch (RemoteException e) {
3309                }
3310            }
3311        }
3312        mProcessObservers.finishBroadcast();
3313    }
3314
3315    final void doPendingActivityLaunchesLocked(boolean doResume) {
3316        final int N = mPendingActivityLaunches.size();
3317        if (N <= 0) {
3318            return;
3319        }
3320        for (int i=0; i<N; i++) {
3321            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3322            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3323                    doResume && i == (N-1), null);
3324        }
3325        mPendingActivityLaunches.clear();
3326    }
3327
3328    @Override
3329    public final int startActivity(IApplicationThread caller, String callingPackage,
3330            Intent intent, String resolvedType, IBinder resultTo,
3331            String resultWho, int requestCode, int startFlags,
3332            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3333        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3334                resultWho, requestCode,
3335                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3336    }
3337
3338    @Override
3339    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3340            Intent intent, String resolvedType, IBinder resultTo,
3341            String resultWho, int requestCode, int startFlags,
3342            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3343        enforceNotIsolatedCaller("startActivity");
3344        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3345                false, true, "startActivity", null);
3346        // TODO: Switch to user app stacks here.
3347        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3348                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3349                null, null, options, userId, null);
3350    }
3351
3352    @Override
3353    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3354            Intent intent, String resolvedType, IBinder resultTo,
3355            String resultWho, int requestCode, int startFlags, String profileFile,
3356            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3357        enforceNotIsolatedCaller("startActivityAndWait");
3358        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3359                false, true, "startActivityAndWait", null);
3360        WaitResult res = new WaitResult();
3361        // TODO: Switch to user app stacks here.
3362        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3363                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3364                res, null, options, UserHandle.getCallingUserId(), null);
3365        return res;
3366    }
3367
3368    @Override
3369    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3370            Intent intent, String resolvedType, IBinder resultTo,
3371            String resultWho, int requestCode, int startFlags, Configuration config,
3372            Bundle options, int userId) {
3373        enforceNotIsolatedCaller("startActivityWithConfig");
3374        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3375                false, true, "startActivityWithConfig", null);
3376        // TODO: Switch to user app stacks here.
3377        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3378                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3379                null, null, null, config, options, userId, null);
3380        return ret;
3381    }
3382
3383    @Override
3384    public int startActivityIntentSender(IApplicationThread caller,
3385            IntentSender intent, Intent fillInIntent, String resolvedType,
3386            IBinder resultTo, String resultWho, int requestCode,
3387            int flagsMask, int flagsValues, Bundle options) {
3388        enforceNotIsolatedCaller("startActivityIntentSender");
3389        // Refuse possible leaked file descriptors
3390        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3391            throw new IllegalArgumentException("File descriptors passed in Intent");
3392        }
3393
3394        IIntentSender sender = intent.getTarget();
3395        if (!(sender instanceof PendingIntentRecord)) {
3396            throw new IllegalArgumentException("Bad PendingIntent object");
3397        }
3398
3399        PendingIntentRecord pir = (PendingIntentRecord)sender;
3400
3401        synchronized (this) {
3402            // If this is coming from the currently resumed activity, it is
3403            // effectively saying that app switches are allowed at this point.
3404            final ActivityStack stack = getFocusedStack();
3405            if (stack.mResumedActivity != null &&
3406                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3407                mAppSwitchesAllowedTime = 0;
3408            }
3409        }
3410        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3411                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3412        return ret;
3413    }
3414
3415    @Override
3416    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3417            Intent intent, String resolvedType, IVoiceInteractionSession session,
3418            IVoiceInteractor interactor, int startFlags, String profileFile,
3419            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3420        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3421                != PackageManager.PERMISSION_GRANTED) {
3422            String msg = "Permission Denial: startVoiceActivity() from pid="
3423                    + Binder.getCallingPid()
3424                    + ", uid=" + Binder.getCallingUid()
3425                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3426            Slog.w(TAG, msg);
3427            throw new SecurityException(msg);
3428        }
3429        if (session == null || interactor == null) {
3430            throw new NullPointerException("null session or interactor");
3431        }
3432        userId = handleIncomingUser(callingPid, callingUid, userId,
3433                false, true, "startVoiceActivity", null);
3434        // TODO: Switch to user app stacks here.
3435        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3436                resolvedType, session, interactor, null, null, 0, startFlags,
3437                profileFile, profileFd, null, null, options, userId, null);
3438    }
3439
3440    @Override
3441    public boolean startNextMatchingActivity(IBinder callingActivity,
3442            Intent intent, Bundle options) {
3443        // Refuse possible leaked file descriptors
3444        if (intent != null && intent.hasFileDescriptors() == true) {
3445            throw new IllegalArgumentException("File descriptors passed in Intent");
3446        }
3447
3448        synchronized (this) {
3449            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3450            if (r == null) {
3451                ActivityOptions.abort(options);
3452                return false;
3453            }
3454            if (r.app == null || r.app.thread == null) {
3455                // The caller is not running...  d'oh!
3456                ActivityOptions.abort(options);
3457                return false;
3458            }
3459            intent = new Intent(intent);
3460            // The caller is not allowed to change the data.
3461            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3462            // And we are resetting to find the next component...
3463            intent.setComponent(null);
3464
3465            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3466
3467            ActivityInfo aInfo = null;
3468            try {
3469                List<ResolveInfo> resolves =
3470                    AppGlobals.getPackageManager().queryIntentActivities(
3471                            intent, r.resolvedType,
3472                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3473                            UserHandle.getCallingUserId());
3474
3475                // Look for the original activity in the list...
3476                final int N = resolves != null ? resolves.size() : 0;
3477                for (int i=0; i<N; i++) {
3478                    ResolveInfo rInfo = resolves.get(i);
3479                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3480                            && rInfo.activityInfo.name.equals(r.info.name)) {
3481                        // We found the current one...  the next matching is
3482                        // after it.
3483                        i++;
3484                        if (i<N) {
3485                            aInfo = resolves.get(i).activityInfo;
3486                        }
3487                        if (debug) {
3488                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3489                                    + "/" + r.info.name);
3490                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3491                                    + "/" + aInfo.name);
3492                        }
3493                        break;
3494                    }
3495                }
3496            } catch (RemoteException e) {
3497            }
3498
3499            if (aInfo == null) {
3500                // Nobody who is next!
3501                ActivityOptions.abort(options);
3502                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3503                return false;
3504            }
3505
3506            intent.setComponent(new ComponentName(
3507                    aInfo.applicationInfo.packageName, aInfo.name));
3508            intent.setFlags(intent.getFlags()&~(
3509                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3510                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3511                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3512                    Intent.FLAG_ACTIVITY_NEW_TASK));
3513
3514            // Okay now we need to start the new activity, replacing the
3515            // currently running activity.  This is a little tricky because
3516            // we want to start the new one as if the current one is finished,
3517            // but not finish the current one first so that there is no flicker.
3518            // And thus...
3519            final boolean wasFinishing = r.finishing;
3520            r.finishing = true;
3521
3522            // Propagate reply information over to the new activity.
3523            final ActivityRecord resultTo = r.resultTo;
3524            final String resultWho = r.resultWho;
3525            final int requestCode = r.requestCode;
3526            r.resultTo = null;
3527            if (resultTo != null) {
3528                resultTo.removeResultsLocked(r, resultWho, requestCode);
3529            }
3530
3531            final long origId = Binder.clearCallingIdentity();
3532            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3533                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3534                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3535                    options, false, null, null);
3536            Binder.restoreCallingIdentity(origId);
3537
3538            r.finishing = wasFinishing;
3539            if (res != ActivityManager.START_SUCCESS) {
3540                return false;
3541            }
3542            return true;
3543        }
3544    }
3545
3546    final int startActivityInPackage(int uid, String callingPackage,
3547            Intent intent, String resolvedType, IBinder resultTo,
3548            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3549                    IActivityContainer container) {
3550
3551        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3552                false, true, "startActivityInPackage", null);
3553
3554        // TODO: Switch to user app stacks here.
3555        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3556                null, null, resultTo, resultWho, requestCode, startFlags,
3557                null, null, null, null, options, userId, container);
3558        return ret;
3559    }
3560
3561    @Override
3562    public final int startActivities(IApplicationThread caller, String callingPackage,
3563            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3564            int userId) {
3565        enforceNotIsolatedCaller("startActivities");
3566        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3567                false, true, "startActivity", null);
3568        // TODO: Switch to user app stacks here.
3569        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3570                resolvedTypes, resultTo, options, userId);
3571        return ret;
3572    }
3573
3574    final int startActivitiesInPackage(int uid, String callingPackage,
3575            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3576            Bundle options, int userId) {
3577
3578        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3579                false, true, "startActivityInPackage", null);
3580        // TODO: Switch to user app stacks here.
3581        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3582                resultTo, options, userId);
3583        return ret;
3584    }
3585
3586    final void addRecentTaskLocked(TaskRecord task) {
3587        int N = mRecentTasks.size();
3588        // Quick case: check if the top-most recent task is the same.
3589        if (N > 0 && mRecentTasks.get(0) == task) {
3590            return;
3591        }
3592        // Another quick case: never add voice sessions.
3593        if (task.voiceSession != null) {
3594            return;
3595        }
3596        // Remove any existing entries that are the same kind of task.
3597        final Intent intent = task.intent;
3598        final boolean document = intent != null && intent.isDocument();
3599        final ComponentName comp = intent.getComponent();
3600
3601        int maxRecents = task.maxRecents - 1;
3602        for (int i=0; i<N; i++) {
3603            TaskRecord tr = mRecentTasks.get(i);
3604            if (task != tr) {
3605                if (task.userId != tr.userId) {
3606                    continue;
3607                }
3608                if (i > MAX_RECENT_BITMAPS) {
3609                    tr.freeLastThumbnail();
3610                }
3611                final Intent trIntent = tr.intent;
3612                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3613                    (intent == null || !intent.filterEquals(trIntent))) {
3614                    continue;
3615                }
3616                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3617                if (document && trIsDocument) {
3618                    // These are the same document activity (not necessarily the same doc).
3619                    if (maxRecents > 0) {
3620                        --maxRecents;
3621                        continue;
3622                    }
3623                    // Hit the maximum number of documents for this task. Fall through
3624                    // and remove this document from recents.
3625                } else if (document || trIsDocument) {
3626                    // Only one of these is a document. Not the droid we're looking for.
3627                    continue;
3628                }
3629            }
3630
3631            // Either task and tr are the same or, their affinities match or their intents match
3632            // and neither of them is a document, or they are documents using the same activity
3633            // and their maxRecents has been reached.
3634            tr.disposeThumbnail();
3635            mRecentTasks.remove(i);
3636            i--;
3637            N--;
3638            if (task.intent == null) {
3639                // If the new recent task we are adding is not fully
3640                // specified, then replace it with the existing recent task.
3641                task = tr;
3642            }
3643            mTaskPersister.notify(tr, false);
3644        }
3645        if (N >= MAX_RECENT_TASKS) {
3646            mRecentTasks.remove(N-1).disposeThumbnail();
3647        }
3648        mRecentTasks.add(0, task);
3649    }
3650
3651    @Override
3652    public void reportActivityFullyDrawn(IBinder token) {
3653        synchronized (this) {
3654            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3655            if (r == null) {
3656                return;
3657            }
3658            r.reportFullyDrawnLocked();
3659        }
3660    }
3661
3662    @Override
3663    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3664        synchronized (this) {
3665            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3666            if (r == null) {
3667                return;
3668            }
3669            final long origId = Binder.clearCallingIdentity();
3670            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3671            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3672                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3673            if (config != null) {
3674                r.frozenBeforeDestroy = true;
3675                if (!updateConfigurationLocked(config, r, false, false)) {
3676                    mStackSupervisor.resumeTopActivitiesLocked();
3677                }
3678            }
3679            Binder.restoreCallingIdentity(origId);
3680        }
3681    }
3682
3683    @Override
3684    public int getRequestedOrientation(IBinder token) {
3685        synchronized (this) {
3686            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3687            if (r == null) {
3688                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3689            }
3690            return mWindowManager.getAppOrientation(r.appToken);
3691        }
3692    }
3693
3694    /**
3695     * This is the internal entry point for handling Activity.finish().
3696     *
3697     * @param token The Binder token referencing the Activity we want to finish.
3698     * @param resultCode Result code, if any, from this Activity.
3699     * @param resultData Result data (Intent), if any, from this Activity.
3700     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3701     *            the root Activity in the task.
3702     *
3703     * @return Returns true if the activity successfully finished, or false if it is still running.
3704     */
3705    @Override
3706    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3707            boolean finishTask) {
3708        // Refuse possible leaked file descriptors
3709        if (resultData != null && resultData.hasFileDescriptors() == true) {
3710            throw new IllegalArgumentException("File descriptors passed in Intent");
3711        }
3712
3713        synchronized(this) {
3714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3715            if (r == null) {
3716                return true;
3717            }
3718            // Keep track of the root activity of the task before we finish it
3719            TaskRecord tr = r.task;
3720            ActivityRecord rootR = tr.getRootActivity();
3721            // Do not allow task to finish in Lock Task mode.
3722            if (tr == mStackSupervisor.mLockTaskModeTask) {
3723                if (rootR == r) {
3724                    mStackSupervisor.showLockTaskToast();
3725                    return false;
3726                }
3727            }
3728            if (mController != null) {
3729                // Find the first activity that is not finishing.
3730                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3731                if (next != null) {
3732                    // ask watcher if this is allowed
3733                    boolean resumeOK = true;
3734                    try {
3735                        resumeOK = mController.activityResuming(next.packageName);
3736                    } catch (RemoteException e) {
3737                        mController = null;
3738                        Watchdog.getInstance().setActivityController(null);
3739                    }
3740
3741                    if (!resumeOK) {
3742                        return false;
3743                    }
3744                }
3745            }
3746            final long origId = Binder.clearCallingIdentity();
3747            try {
3748                boolean res;
3749                if (finishTask && r == rootR) {
3750                    // If requested, remove the task that is associated to this activity only if it
3751                    // was the root activity in the task.  The result code and data is ignored because
3752                    // we don't support returning them across task boundaries.
3753                    res = removeTaskByIdLocked(tr.taskId, 0);
3754                } else {
3755                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3756                            resultData, "app-request", true);
3757                }
3758                return res;
3759            } finally {
3760                Binder.restoreCallingIdentity(origId);
3761            }
3762        }
3763    }
3764
3765    @Override
3766    public final void finishHeavyWeightApp() {
3767        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3768                != PackageManager.PERMISSION_GRANTED) {
3769            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3770                    + Binder.getCallingPid()
3771                    + ", uid=" + Binder.getCallingUid()
3772                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3773            Slog.w(TAG, msg);
3774            throw new SecurityException(msg);
3775        }
3776
3777        synchronized(this) {
3778            if (mHeavyWeightProcess == null) {
3779                return;
3780            }
3781
3782            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3783                    mHeavyWeightProcess.activities);
3784            for (int i=0; i<activities.size(); i++) {
3785                ActivityRecord r = activities.get(i);
3786                if (!r.finishing) {
3787                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3788                            null, "finish-heavy", true);
3789                }
3790            }
3791
3792            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3793                    mHeavyWeightProcess.userId, 0));
3794            mHeavyWeightProcess = null;
3795        }
3796    }
3797
3798    @Override
3799    public void crashApplication(int uid, int initialPid, String packageName,
3800            String message) {
3801        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3802                != PackageManager.PERMISSION_GRANTED) {
3803            String msg = "Permission Denial: crashApplication() from pid="
3804                    + Binder.getCallingPid()
3805                    + ", uid=" + Binder.getCallingUid()
3806                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3807            Slog.w(TAG, msg);
3808            throw new SecurityException(msg);
3809        }
3810
3811        synchronized(this) {
3812            ProcessRecord proc = null;
3813
3814            // Figure out which process to kill.  We don't trust that initialPid
3815            // still has any relation to current pids, so must scan through the
3816            // list.
3817            synchronized (mPidsSelfLocked) {
3818                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3819                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3820                    if (p.uid != uid) {
3821                        continue;
3822                    }
3823                    if (p.pid == initialPid) {
3824                        proc = p;
3825                        break;
3826                    }
3827                    if (p.pkgList.containsKey(packageName)) {
3828                        proc = p;
3829                    }
3830                }
3831            }
3832
3833            if (proc == null) {
3834                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3835                        + " initialPid=" + initialPid
3836                        + " packageName=" + packageName);
3837                return;
3838            }
3839
3840            if (proc.thread != null) {
3841                if (proc.pid == Process.myPid()) {
3842                    Log.w(TAG, "crashApplication: trying to crash self!");
3843                    return;
3844                }
3845                long ident = Binder.clearCallingIdentity();
3846                try {
3847                    proc.thread.scheduleCrash(message);
3848                } catch (RemoteException e) {
3849                }
3850                Binder.restoreCallingIdentity(ident);
3851            }
3852        }
3853    }
3854
3855    @Override
3856    public final void finishSubActivity(IBinder token, String resultWho,
3857            int requestCode) {
3858        synchronized(this) {
3859            final long origId = Binder.clearCallingIdentity();
3860            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3861            if (r != null) {
3862                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3863            }
3864            Binder.restoreCallingIdentity(origId);
3865        }
3866    }
3867
3868    @Override
3869    public boolean finishActivityAffinity(IBinder token) {
3870        synchronized(this) {
3871            final long origId = Binder.clearCallingIdentity();
3872            try {
3873                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3874
3875                ActivityRecord rootR = r.task.getRootActivity();
3876                // Do not allow task to finish in Lock Task mode.
3877                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3878                    if (rootR == r) {
3879                        mStackSupervisor.showLockTaskToast();
3880                        return false;
3881                    }
3882                }
3883                boolean res = false;
3884                if (r != null) {
3885                    res = r.task.stack.finishActivityAffinityLocked(r);
3886                }
3887                return res;
3888            } finally {
3889                Binder.restoreCallingIdentity(origId);
3890            }
3891        }
3892    }
3893
3894    @Override
3895    public void finishVoiceTask(IVoiceInteractionSession session) {
3896        synchronized(this) {
3897            final long origId = Binder.clearCallingIdentity();
3898            try {
3899                mStackSupervisor.finishVoiceTask(session);
3900            } finally {
3901                Binder.restoreCallingIdentity(origId);
3902            }
3903        }
3904
3905    }
3906
3907    @Override
3908    public boolean willActivityBeVisible(IBinder token) {
3909        synchronized(this) {
3910            ActivityStack stack = ActivityRecord.getStackLocked(token);
3911            if (stack != null) {
3912                return stack.willActivityBeVisibleLocked(token);
3913            }
3914            return false;
3915        }
3916    }
3917
3918    @Override
3919    public void overridePendingTransition(IBinder token, String packageName,
3920            int enterAnim, int exitAnim) {
3921        synchronized(this) {
3922            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3923            if (self == null) {
3924                return;
3925            }
3926
3927            final long origId = Binder.clearCallingIdentity();
3928
3929            if (self.state == ActivityState.RESUMED
3930                    || self.state == ActivityState.PAUSING) {
3931                mWindowManager.overridePendingAppTransition(packageName,
3932                        enterAnim, exitAnim, null);
3933            }
3934
3935            Binder.restoreCallingIdentity(origId);
3936        }
3937    }
3938
3939    /**
3940     * Main function for removing an existing process from the activity manager
3941     * as a result of that process going away.  Clears out all connections
3942     * to the process.
3943     */
3944    private final void handleAppDiedLocked(ProcessRecord app,
3945            boolean restarting, boolean allowRestart) {
3946        int pid = app.pid;
3947        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3948        if (!restarting) {
3949            removeLruProcessLocked(app);
3950            if (pid > 0) {
3951                ProcessList.remove(pid);
3952            }
3953        }
3954
3955        if (mProfileProc == app) {
3956            clearProfilerLocked();
3957        }
3958
3959        // Remove this application's activities from active lists.
3960        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3961
3962        app.activities.clear();
3963
3964        if (app.instrumentationClass != null) {
3965            Slog.w(TAG, "Crash of app " + app.processName
3966                  + " running instrumentation " + app.instrumentationClass);
3967            Bundle info = new Bundle();
3968            info.putString("shortMsg", "Process crashed.");
3969            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3970        }
3971
3972        if (!restarting) {
3973            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3974                // If there was nothing to resume, and we are not already
3975                // restarting this process, but there is a visible activity that
3976                // is hosted by the process...  then make sure all visible
3977                // activities are running, taking care of restarting this
3978                // process.
3979                if (hasVisibleActivities) {
3980                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3981                }
3982            }
3983        }
3984    }
3985
3986    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3987        IBinder threadBinder = thread.asBinder();
3988        // Find the application record.
3989        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3990            ProcessRecord rec = mLruProcesses.get(i);
3991            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3992                return i;
3993            }
3994        }
3995        return -1;
3996    }
3997
3998    final ProcessRecord getRecordForAppLocked(
3999            IApplicationThread thread) {
4000        if (thread == null) {
4001            return null;
4002        }
4003
4004        int appIndex = getLRURecordIndexForAppLocked(thread);
4005        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4006    }
4007
4008    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4009        // If there are no longer any background processes running,
4010        // and the app that died was not running instrumentation,
4011        // then tell everyone we are now low on memory.
4012        boolean haveBg = false;
4013        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4014            ProcessRecord rec = mLruProcesses.get(i);
4015            if (rec.thread != null
4016                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4017                haveBg = true;
4018                break;
4019            }
4020        }
4021
4022        if (!haveBg) {
4023            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4024            if (doReport) {
4025                long now = SystemClock.uptimeMillis();
4026                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4027                    doReport = false;
4028                } else {
4029                    mLastMemUsageReportTime = now;
4030                }
4031            }
4032            final ArrayList<ProcessMemInfo> memInfos
4033                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4034            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4035            long now = SystemClock.uptimeMillis();
4036            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4037                ProcessRecord rec = mLruProcesses.get(i);
4038                if (rec == dyingProc || rec.thread == null) {
4039                    continue;
4040                }
4041                if (doReport) {
4042                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4043                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4044                }
4045                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4046                    // The low memory report is overriding any current
4047                    // state for a GC request.  Make sure to do
4048                    // heavy/important/visible/foreground processes first.
4049                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4050                        rec.lastRequestedGc = 0;
4051                    } else {
4052                        rec.lastRequestedGc = rec.lastLowMemory;
4053                    }
4054                    rec.reportLowMemory = true;
4055                    rec.lastLowMemory = now;
4056                    mProcessesToGc.remove(rec);
4057                    addProcessToGcListLocked(rec);
4058                }
4059            }
4060            if (doReport) {
4061                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4062                mHandler.sendMessage(msg);
4063            }
4064            scheduleAppGcsLocked();
4065        }
4066    }
4067
4068    final void appDiedLocked(ProcessRecord app, int pid,
4069            IApplicationThread thread) {
4070
4071        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4072        synchronized (stats) {
4073            stats.noteProcessDiedLocked(app.info.uid, pid);
4074        }
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) Process.killProcess(app.pid);
4315            } catch (RemoteException e) {
4316                mController = null;
4317                Watchdog.getInstance().setActivityController(null);
4318            }
4319        }
4320
4321        long anrTime = SystemClock.uptimeMillis();
4322        if (MONITOR_CPU_USAGE) {
4323            updateCpuStatsNow();
4324        }
4325
4326        synchronized (this) {
4327            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4328            if (mShuttingDown) {
4329                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4330                return;
4331            } else if (app.notResponding) {
4332                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4333                return;
4334            } else if (app.crashing) {
4335                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4336                return;
4337            }
4338
4339            // In case we come through here for the same app before completing
4340            // this one, mark as anring now so we will bail out.
4341            app.notResponding = true;
4342
4343            // Log the ANR to the event log.
4344            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4345                    app.processName, app.info.flags, annotation);
4346
4347            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4348            firstPids.add(app.pid);
4349
4350            int parentPid = app.pid;
4351            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4352            if (parentPid != app.pid) firstPids.add(parentPid);
4353
4354            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4355
4356            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4357                ProcessRecord r = mLruProcesses.get(i);
4358                if (r != null && r.thread != null) {
4359                    int pid = r.pid;
4360                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4361                        if (r.persistent) {
4362                            firstPids.add(pid);
4363                        } else {
4364                            lastPids.put(pid, Boolean.TRUE);
4365                        }
4366                    }
4367                }
4368            }
4369        }
4370
4371        // Log the ANR to the main log.
4372        StringBuilder info = new StringBuilder();
4373        info.setLength(0);
4374        info.append("ANR in ").append(app.processName);
4375        if (activity != null && activity.shortComponentName != null) {
4376            info.append(" (").append(activity.shortComponentName).append(")");
4377        }
4378        info.append("\n");
4379        info.append("PID: ").append(app.pid).append("\n");
4380        if (annotation != null) {
4381            info.append("Reason: ").append(annotation).append("\n");
4382        }
4383        if (parent != null && parent != activity) {
4384            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4385        }
4386
4387        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4388
4389        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4390                NATIVE_STACKS_OF_INTEREST);
4391
4392        String cpuInfo = null;
4393        if (MONITOR_CPU_USAGE) {
4394            updateCpuStatsNow();
4395            synchronized (mProcessCpuThread) {
4396                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4397            }
4398            info.append(processCpuTracker.printCurrentLoad());
4399            info.append(cpuInfo);
4400        }
4401
4402        info.append(processCpuTracker.printCurrentState(anrTime));
4403
4404        Slog.e(TAG, info.toString());
4405        if (tracesFile == null) {
4406            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4407            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4408        }
4409
4410        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4411                cpuInfo, tracesFile, null);
4412
4413        if (mController != null) {
4414            try {
4415                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4416                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4417                if (res != 0) {
4418                    if (res < 0 && app.pid != MY_PID) {
4419                        Process.killProcess(app.pid);
4420                    } else {
4421                        synchronized (this) {
4422                            mServices.scheduleServiceTimeoutLocked(app);
4423                        }
4424                    }
4425                    return;
4426                }
4427            } catch (RemoteException e) {
4428                mController = null;
4429                Watchdog.getInstance().setActivityController(null);
4430            }
4431        }
4432
4433        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4434        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4435                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4436
4437        synchronized (this) {
4438            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4439                killUnneededProcessLocked(app, "background ANR");
4440                return;
4441            }
4442
4443            // Set the app's notResponding state, and look up the errorReportReceiver
4444            makeAppNotRespondingLocked(app,
4445                    activity != null ? activity.shortComponentName : null,
4446                    annotation != null ? "ANR " + annotation : "ANR",
4447                    info.toString());
4448
4449            // Bring up the infamous App Not Responding dialog
4450            Message msg = Message.obtain();
4451            HashMap<String, Object> map = new HashMap<String, Object>();
4452            msg.what = SHOW_NOT_RESPONDING_MSG;
4453            msg.obj = map;
4454            msg.arg1 = aboveSystem ? 1 : 0;
4455            map.put("app", app);
4456            if (activity != null) {
4457                map.put("activity", activity);
4458            }
4459
4460            mHandler.sendMessage(msg);
4461        }
4462    }
4463
4464    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4465        if (!mLaunchWarningShown) {
4466            mLaunchWarningShown = true;
4467            mHandler.post(new Runnable() {
4468                @Override
4469                public void run() {
4470                    synchronized (ActivityManagerService.this) {
4471                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4472                        d.show();
4473                        mHandler.postDelayed(new Runnable() {
4474                            @Override
4475                            public void run() {
4476                                synchronized (ActivityManagerService.this) {
4477                                    d.dismiss();
4478                                    mLaunchWarningShown = false;
4479                                }
4480                            }
4481                        }, 4000);
4482                    }
4483                }
4484            });
4485        }
4486    }
4487
4488    @Override
4489    public boolean clearApplicationUserData(final String packageName,
4490            final IPackageDataObserver observer, int userId) {
4491        enforceNotIsolatedCaller("clearApplicationUserData");
4492        int uid = Binder.getCallingUid();
4493        int pid = Binder.getCallingPid();
4494        userId = handleIncomingUser(pid, uid,
4495                userId, false, true, "clearApplicationUserData", null);
4496        long callingId = Binder.clearCallingIdentity();
4497        try {
4498            IPackageManager pm = AppGlobals.getPackageManager();
4499            int pkgUid = -1;
4500            synchronized(this) {
4501                try {
4502                    pkgUid = pm.getPackageUid(packageName, userId);
4503                } catch (RemoteException e) {
4504                }
4505                if (pkgUid == -1) {
4506                    Slog.w(TAG, "Invalid packageName: " + packageName);
4507                    if (observer != null) {
4508                        try {
4509                            observer.onRemoveCompleted(packageName, false);
4510                        } catch (RemoteException e) {
4511                            Slog.i(TAG, "Observer no longer exists.");
4512                        }
4513                    }
4514                    return false;
4515                }
4516                if (uid == pkgUid || checkComponentPermission(
4517                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4518                        pid, uid, -1, true)
4519                        == PackageManager.PERMISSION_GRANTED) {
4520                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4521                } else {
4522                    throw new SecurityException("PID " + pid + " does not have permission "
4523                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4524                                    + " of package " + packageName);
4525                }
4526            }
4527
4528            try {
4529                // Clear application user data
4530                pm.clearApplicationUserData(packageName, observer, userId);
4531
4532                // Remove all permissions granted from/to this package
4533                removeUriPermissionsForPackageLocked(packageName, userId, true);
4534
4535                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4536                        Uri.fromParts("package", packageName, null));
4537                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4538                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4539                        null, null, 0, null, null, null, false, false, userId);
4540            } catch (RemoteException e) {
4541            }
4542        } finally {
4543            Binder.restoreCallingIdentity(callingId);
4544        }
4545        return true;
4546    }
4547
4548    @Override
4549    public void killBackgroundProcesses(final String packageName, int userId) {
4550        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4551                != PackageManager.PERMISSION_GRANTED &&
4552                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4553                        != PackageManager.PERMISSION_GRANTED) {
4554            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4555                    + Binder.getCallingPid()
4556                    + ", uid=" + Binder.getCallingUid()
4557                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4558            Slog.w(TAG, msg);
4559            throw new SecurityException(msg);
4560        }
4561
4562        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4563                userId, true, true, "killBackgroundProcesses", null);
4564        long callingId = Binder.clearCallingIdentity();
4565        try {
4566            IPackageManager pm = AppGlobals.getPackageManager();
4567            synchronized(this) {
4568                int appId = -1;
4569                try {
4570                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4571                } catch (RemoteException e) {
4572                }
4573                if (appId == -1) {
4574                    Slog.w(TAG, "Invalid packageName: " + packageName);
4575                    return;
4576                }
4577                killPackageProcessesLocked(packageName, appId, userId,
4578                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4579            }
4580        } finally {
4581            Binder.restoreCallingIdentity(callingId);
4582        }
4583    }
4584
4585    @Override
4586    public void killAllBackgroundProcesses() {
4587        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4588                != PackageManager.PERMISSION_GRANTED) {
4589            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4590                    + Binder.getCallingPid()
4591                    + ", uid=" + Binder.getCallingUid()
4592                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4593            Slog.w(TAG, msg);
4594            throw new SecurityException(msg);
4595        }
4596
4597        long callingId = Binder.clearCallingIdentity();
4598        try {
4599            synchronized(this) {
4600                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4601                final int NP = mProcessNames.getMap().size();
4602                for (int ip=0; ip<NP; ip++) {
4603                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4604                    final int NA = apps.size();
4605                    for (int ia=0; ia<NA; ia++) {
4606                        ProcessRecord app = apps.valueAt(ia);
4607                        if (app.persistent) {
4608                            // we don't kill persistent processes
4609                            continue;
4610                        }
4611                        if (app.removed) {
4612                            procs.add(app);
4613                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4614                            app.removed = true;
4615                            procs.add(app);
4616                        }
4617                    }
4618                }
4619
4620                int N = procs.size();
4621                for (int i=0; i<N; i++) {
4622                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4623                }
4624                mAllowLowerMemLevel = true;
4625                updateOomAdjLocked();
4626                doLowMemReportIfNeededLocked(null);
4627            }
4628        } finally {
4629            Binder.restoreCallingIdentity(callingId);
4630        }
4631    }
4632
4633    @Override
4634    public void forceStopPackage(final String packageName, int userId) {
4635        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4636                != PackageManager.PERMISSION_GRANTED) {
4637            String msg = "Permission Denial: forceStopPackage() from pid="
4638                    + Binder.getCallingPid()
4639                    + ", uid=" + Binder.getCallingUid()
4640                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4641            Slog.w(TAG, msg);
4642            throw new SecurityException(msg);
4643        }
4644        final int callingPid = Binder.getCallingPid();
4645        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4646                userId, true, true, "forceStopPackage", null);
4647        long callingId = Binder.clearCallingIdentity();
4648        try {
4649            IPackageManager pm = AppGlobals.getPackageManager();
4650            synchronized(this) {
4651                int[] users = userId == UserHandle.USER_ALL
4652                        ? getUsersLocked() : new int[] { userId };
4653                for (int user : users) {
4654                    int pkgUid = -1;
4655                    try {
4656                        pkgUid = pm.getPackageUid(packageName, user);
4657                    } catch (RemoteException e) {
4658                    }
4659                    if (pkgUid == -1) {
4660                        Slog.w(TAG, "Invalid packageName: " + packageName);
4661                        continue;
4662                    }
4663                    try {
4664                        pm.setPackageStoppedState(packageName, true, user);
4665                    } catch (RemoteException e) {
4666                    } catch (IllegalArgumentException e) {
4667                        Slog.w(TAG, "Failed trying to unstop package "
4668                                + packageName + ": " + e);
4669                    }
4670                    if (isUserRunningLocked(user, false)) {
4671                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4672                    }
4673                }
4674            }
4675        } finally {
4676            Binder.restoreCallingIdentity(callingId);
4677        }
4678    }
4679
4680    /*
4681     * The pkg name and app id have to be specified.
4682     */
4683    @Override
4684    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4685        if (pkg == null) {
4686            return;
4687        }
4688        // Make sure the uid is valid.
4689        if (appid < 0) {
4690            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4691            return;
4692        }
4693        int callerUid = Binder.getCallingUid();
4694        // Only the system server can kill an application
4695        if (callerUid == Process.SYSTEM_UID) {
4696            // Post an aysnc message to kill the application
4697            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4698            msg.arg1 = appid;
4699            msg.arg2 = 0;
4700            Bundle bundle = new Bundle();
4701            bundle.putString("pkg", pkg);
4702            bundle.putString("reason", reason);
4703            msg.obj = bundle;
4704            mHandler.sendMessage(msg);
4705        } else {
4706            throw new SecurityException(callerUid + " cannot kill pkg: " +
4707                    pkg);
4708        }
4709    }
4710
4711    @Override
4712    public void closeSystemDialogs(String reason) {
4713        enforceNotIsolatedCaller("closeSystemDialogs");
4714
4715        final int pid = Binder.getCallingPid();
4716        final int uid = Binder.getCallingUid();
4717        final long origId = Binder.clearCallingIdentity();
4718        try {
4719            synchronized (this) {
4720                // Only allow this from foreground processes, so that background
4721                // applications can't abuse it to prevent system UI from being shown.
4722                if (uid >= Process.FIRST_APPLICATION_UID) {
4723                    ProcessRecord proc;
4724                    synchronized (mPidsSelfLocked) {
4725                        proc = mPidsSelfLocked.get(pid);
4726                    }
4727                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4728                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4729                                + " from background process " + proc);
4730                        return;
4731                    }
4732                }
4733                closeSystemDialogsLocked(reason);
4734            }
4735        } finally {
4736            Binder.restoreCallingIdentity(origId);
4737        }
4738    }
4739
4740    void closeSystemDialogsLocked(String reason) {
4741        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4742        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4743                | Intent.FLAG_RECEIVER_FOREGROUND);
4744        if (reason != null) {
4745            intent.putExtra("reason", reason);
4746        }
4747        mWindowManager.closeSystemDialogs(reason);
4748
4749        mStackSupervisor.closeSystemDialogsLocked();
4750
4751        broadcastIntentLocked(null, null, intent, null,
4752                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4753                Process.SYSTEM_UID, UserHandle.USER_ALL);
4754    }
4755
4756    @Override
4757    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4758        enforceNotIsolatedCaller("getProcessMemoryInfo");
4759        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4760        for (int i=pids.length-1; i>=0; i--) {
4761            ProcessRecord proc;
4762            int oomAdj;
4763            synchronized (this) {
4764                synchronized (mPidsSelfLocked) {
4765                    proc = mPidsSelfLocked.get(pids[i]);
4766                    oomAdj = proc != null ? proc.setAdj : 0;
4767                }
4768            }
4769            infos[i] = new Debug.MemoryInfo();
4770            Debug.getMemoryInfo(pids[i], infos[i]);
4771            if (proc != null) {
4772                synchronized (this) {
4773                    if (proc.thread != null && proc.setAdj == oomAdj) {
4774                        // Record this for posterity if the process has been stable.
4775                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4776                                infos[i].getTotalUss(), false, proc.pkgList);
4777                    }
4778                }
4779            }
4780        }
4781        return infos;
4782    }
4783
4784    @Override
4785    public long[] getProcessPss(int[] pids) {
4786        enforceNotIsolatedCaller("getProcessPss");
4787        long[] pss = new long[pids.length];
4788        for (int i=pids.length-1; i>=0; i--) {
4789            ProcessRecord proc;
4790            int oomAdj;
4791            synchronized (this) {
4792                synchronized (mPidsSelfLocked) {
4793                    proc = mPidsSelfLocked.get(pids[i]);
4794                    oomAdj = proc != null ? proc.setAdj : 0;
4795                }
4796            }
4797            long[] tmpUss = new long[1];
4798            pss[i] = Debug.getPss(pids[i], tmpUss);
4799            if (proc != null) {
4800                synchronized (this) {
4801                    if (proc.thread != null && proc.setAdj == oomAdj) {
4802                        // Record this for posterity if the process has been stable.
4803                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4804                    }
4805                }
4806            }
4807        }
4808        return pss;
4809    }
4810
4811    @Override
4812    public void killApplicationProcess(String processName, int uid) {
4813        if (processName == null) {
4814            return;
4815        }
4816
4817        int callerUid = Binder.getCallingUid();
4818        // Only the system server can kill an application
4819        if (callerUid == Process.SYSTEM_UID) {
4820            synchronized (this) {
4821                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4822                if (app != null && app.thread != null) {
4823                    try {
4824                        app.thread.scheduleSuicide();
4825                    } catch (RemoteException e) {
4826                        // If the other end already died, then our work here is done.
4827                    }
4828                } else {
4829                    Slog.w(TAG, "Process/uid not found attempting kill of "
4830                            + processName + " / " + uid);
4831                }
4832            }
4833        } else {
4834            throw new SecurityException(callerUid + " cannot kill app process: " +
4835                    processName);
4836        }
4837    }
4838
4839    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4840        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4841                false, true, false, false, UserHandle.getUserId(uid), reason);
4842        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4843                Uri.fromParts("package", packageName, null));
4844        if (!mProcessesReady) {
4845            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4846                    | Intent.FLAG_RECEIVER_FOREGROUND);
4847        }
4848        intent.putExtra(Intent.EXTRA_UID, uid);
4849        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4850        broadcastIntentLocked(null, null, intent,
4851                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4852                false, false,
4853                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4854    }
4855
4856    private void forceStopUserLocked(int userId, String reason) {
4857        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4858        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4859        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4860                | Intent.FLAG_RECEIVER_FOREGROUND);
4861        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4862        broadcastIntentLocked(null, null, intent,
4863                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4864                false, false,
4865                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4866    }
4867
4868    private final boolean killPackageProcessesLocked(String packageName, int appId,
4869            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4870            boolean doit, boolean evenPersistent, String reason) {
4871        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4872
4873        // Remove all processes this package may have touched: all with the
4874        // same UID (except for the system or root user), and all whose name
4875        // matches the package name.
4876        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4877        final int NP = mProcessNames.getMap().size();
4878        for (int ip=0; ip<NP; ip++) {
4879            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4880            final int NA = apps.size();
4881            for (int ia=0; ia<NA; ia++) {
4882                ProcessRecord app = apps.valueAt(ia);
4883                if (app.persistent && !evenPersistent) {
4884                    // we don't kill persistent processes
4885                    continue;
4886                }
4887                if (app.removed) {
4888                    if (doit) {
4889                        procs.add(app);
4890                    }
4891                    continue;
4892                }
4893
4894                // Skip process if it doesn't meet our oom adj requirement.
4895                if (app.setAdj < minOomAdj) {
4896                    continue;
4897                }
4898
4899                // If no package is specified, we call all processes under the
4900                // give user id.
4901                if (packageName == null) {
4902                    if (app.userId != userId) {
4903                        continue;
4904                    }
4905                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4906                        continue;
4907                    }
4908                // Package has been specified, we want to hit all processes
4909                // that match it.  We need to qualify this by the processes
4910                // that are running under the specified app and user ID.
4911                } else {
4912                    if (UserHandle.getAppId(app.uid) != appId) {
4913                        continue;
4914                    }
4915                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4916                        continue;
4917                    }
4918                    if (!app.pkgList.containsKey(packageName)) {
4919                        continue;
4920                    }
4921                }
4922
4923                // Process has passed all conditions, kill it!
4924                if (!doit) {
4925                    return true;
4926                }
4927                app.removed = true;
4928                procs.add(app);
4929            }
4930        }
4931
4932        int N = procs.size();
4933        for (int i=0; i<N; i++) {
4934            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4935        }
4936        updateOomAdjLocked();
4937        return N > 0;
4938    }
4939
4940    private final boolean forceStopPackageLocked(String name, int appId,
4941            boolean callerWillRestart, boolean purgeCache, boolean doit,
4942            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4943        int i;
4944        int N;
4945
4946        if (userId == UserHandle.USER_ALL && name == null) {
4947            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4948        }
4949
4950        if (appId < 0 && name != null) {
4951            try {
4952                appId = UserHandle.getAppId(
4953                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4954            } catch (RemoteException e) {
4955            }
4956        }
4957
4958        if (doit) {
4959            if (name != null) {
4960                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4961                        + " user=" + userId + ": " + reason);
4962            } else {
4963                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4964            }
4965
4966            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4967            for (int ip=pmap.size()-1; ip>=0; ip--) {
4968                SparseArray<Long> ba = pmap.valueAt(ip);
4969                for (i=ba.size()-1; i>=0; i--) {
4970                    boolean remove = false;
4971                    final int entUid = ba.keyAt(i);
4972                    if (name != null) {
4973                        if (userId == UserHandle.USER_ALL) {
4974                            if (UserHandle.getAppId(entUid) == appId) {
4975                                remove = true;
4976                            }
4977                        } else {
4978                            if (entUid == UserHandle.getUid(userId, appId)) {
4979                                remove = true;
4980                            }
4981                        }
4982                    } else if (UserHandle.getUserId(entUid) == userId) {
4983                        remove = true;
4984                    }
4985                    if (remove) {
4986                        ba.removeAt(i);
4987                    }
4988                }
4989                if (ba.size() == 0) {
4990                    pmap.removeAt(ip);
4991                }
4992            }
4993        }
4994
4995        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4996                -100, callerWillRestart, true, doit, evenPersistent,
4997                name == null ? ("stop user " + userId) : ("stop " + name));
4998
4999        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5000            if (!doit) {
5001                return true;
5002            }
5003            didSomething = true;
5004        }
5005
5006        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5007            if (!doit) {
5008                return true;
5009            }
5010            didSomething = true;
5011        }
5012
5013        if (name == null) {
5014            // Remove all sticky broadcasts from this user.
5015            mStickyBroadcasts.remove(userId);
5016        }
5017
5018        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5019        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5020                userId, providers)) {
5021            if (!doit) {
5022                return true;
5023            }
5024            didSomething = true;
5025        }
5026        N = providers.size();
5027        for (i=0; i<N; i++) {
5028            removeDyingProviderLocked(null, providers.get(i), true);
5029        }
5030
5031        // Remove transient permissions granted from/to this package/user
5032        removeUriPermissionsForPackageLocked(name, userId, false);
5033
5034        if (name == null || uninstalling) {
5035            // Remove pending intents.  For now we only do this when force
5036            // stopping users, because we have some problems when doing this
5037            // for packages -- app widgets are not currently cleaned up for
5038            // such packages, so they can be left with bad pending intents.
5039            if (mIntentSenderRecords.size() > 0) {
5040                Iterator<WeakReference<PendingIntentRecord>> it
5041                        = mIntentSenderRecords.values().iterator();
5042                while (it.hasNext()) {
5043                    WeakReference<PendingIntentRecord> wpir = it.next();
5044                    if (wpir == null) {
5045                        it.remove();
5046                        continue;
5047                    }
5048                    PendingIntentRecord pir = wpir.get();
5049                    if (pir == null) {
5050                        it.remove();
5051                        continue;
5052                    }
5053                    if (name == null) {
5054                        // Stopping user, remove all objects for the user.
5055                        if (pir.key.userId != userId) {
5056                            // Not the same user, skip it.
5057                            continue;
5058                        }
5059                    } else {
5060                        if (UserHandle.getAppId(pir.uid) != appId) {
5061                            // Different app id, skip it.
5062                            continue;
5063                        }
5064                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5065                            // Different user, skip it.
5066                            continue;
5067                        }
5068                        if (!pir.key.packageName.equals(name)) {
5069                            // Different package, skip it.
5070                            continue;
5071                        }
5072                    }
5073                    if (!doit) {
5074                        return true;
5075                    }
5076                    didSomething = true;
5077                    it.remove();
5078                    pir.canceled = true;
5079                    if (pir.key.activity != null) {
5080                        pir.key.activity.pendingResults.remove(pir.ref);
5081                    }
5082                }
5083            }
5084        }
5085
5086        if (doit) {
5087            if (purgeCache && name != null) {
5088                AttributeCache ac = AttributeCache.instance();
5089                if (ac != null) {
5090                    ac.removePackage(name);
5091                }
5092            }
5093            if (mBooted) {
5094                mStackSupervisor.resumeTopActivitiesLocked();
5095                mStackSupervisor.scheduleIdleLocked();
5096            }
5097        }
5098
5099        return didSomething;
5100    }
5101
5102    private final boolean removeProcessLocked(ProcessRecord app,
5103            boolean callerWillRestart, boolean allowRestart, String reason) {
5104        final String name = app.processName;
5105        final int uid = app.uid;
5106        if (DEBUG_PROCESSES) Slog.d(
5107            TAG, "Force removing proc " + app.toShortString() + " (" + name
5108            + "/" + uid + ")");
5109
5110        mProcessNames.remove(name, uid);
5111        mIsolatedProcesses.remove(app.uid);
5112        if (mHeavyWeightProcess == app) {
5113            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5114                    mHeavyWeightProcess.userId, 0));
5115            mHeavyWeightProcess = null;
5116        }
5117        boolean needRestart = false;
5118        if (app.pid > 0 && app.pid != MY_PID) {
5119            int pid = app.pid;
5120            synchronized (mPidsSelfLocked) {
5121                mPidsSelfLocked.remove(pid);
5122                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5123            }
5124            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5125                    app.processName, app.info.uid);
5126            if (app.isolated) {
5127                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5128            }
5129            killUnneededProcessLocked(app, reason);
5130            handleAppDiedLocked(app, true, allowRestart);
5131            removeLruProcessLocked(app);
5132
5133            if (app.persistent && !app.isolated) {
5134                if (!callerWillRestart) {
5135                    addAppLocked(app.info, false, null /* ABI override */);
5136                } else {
5137                    needRestart = true;
5138                }
5139            }
5140        } else {
5141            mRemovedProcesses.add(app);
5142        }
5143
5144        return needRestart;
5145    }
5146
5147    private final void processStartTimedOutLocked(ProcessRecord app) {
5148        final int pid = app.pid;
5149        boolean gone = false;
5150        synchronized (mPidsSelfLocked) {
5151            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5152            if (knownApp != null && knownApp.thread == null) {
5153                mPidsSelfLocked.remove(pid);
5154                gone = true;
5155            }
5156        }
5157
5158        if (gone) {
5159            Slog.w(TAG, "Process " + app + " failed to attach");
5160            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5161                    pid, app.uid, app.processName);
5162            mProcessNames.remove(app.processName, app.uid);
5163            mIsolatedProcesses.remove(app.uid);
5164            if (mHeavyWeightProcess == app) {
5165                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5166                        mHeavyWeightProcess.userId, 0));
5167                mHeavyWeightProcess = null;
5168            }
5169            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5170                    app.processName, app.info.uid);
5171            if (app.isolated) {
5172                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5173            }
5174            // Take care of any launching providers waiting for this process.
5175            checkAppInLaunchingProvidersLocked(app, true);
5176            // Take care of any services that are waiting for the process.
5177            mServices.processStartTimedOutLocked(app);
5178            killUnneededProcessLocked(app, "start timeout");
5179            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5180                Slog.w(TAG, "Unattached app died before backup, skipping");
5181                try {
5182                    IBackupManager bm = IBackupManager.Stub.asInterface(
5183                            ServiceManager.getService(Context.BACKUP_SERVICE));
5184                    bm.agentDisconnected(app.info.packageName);
5185                } catch (RemoteException e) {
5186                    // Can't happen; the backup manager is local
5187                }
5188            }
5189            if (isPendingBroadcastProcessLocked(pid)) {
5190                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5191                skipPendingBroadcastLocked(pid);
5192            }
5193        } else {
5194            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5195        }
5196    }
5197
5198    private final boolean attachApplicationLocked(IApplicationThread thread,
5199            int pid) {
5200
5201        // Find the application record that is being attached...  either via
5202        // the pid if we are running in multiple processes, or just pull the
5203        // next app record if we are emulating process with anonymous threads.
5204        ProcessRecord app;
5205        if (pid != MY_PID && pid >= 0) {
5206            synchronized (mPidsSelfLocked) {
5207                app = mPidsSelfLocked.get(pid);
5208            }
5209        } else {
5210            app = null;
5211        }
5212
5213        if (app == null) {
5214            Slog.w(TAG, "No pending application record for pid " + pid
5215                    + " (IApplicationThread " + thread + "); dropping process");
5216            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5217            if (pid > 0 && pid != MY_PID) {
5218                Process.killProcessQuiet(pid);
5219            } else {
5220                try {
5221                    thread.scheduleExit();
5222                } catch (Exception e) {
5223                    // Ignore exceptions.
5224                }
5225            }
5226            return false;
5227        }
5228
5229        // If this application record is still attached to a previous
5230        // process, clean it up now.
5231        if (app.thread != null) {
5232            handleAppDiedLocked(app, true, true);
5233        }
5234
5235        // Tell the process all about itself.
5236
5237        if (localLOGV) Slog.v(
5238                TAG, "Binding process pid " + pid + " to record " + app);
5239
5240        final String processName = app.processName;
5241        try {
5242            AppDeathRecipient adr = new AppDeathRecipient(
5243                    app, pid, thread);
5244            thread.asBinder().linkToDeath(adr, 0);
5245            app.deathRecipient = adr;
5246        } catch (RemoteException e) {
5247            app.resetPackageList(mProcessStats);
5248            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5249            return false;
5250        }
5251
5252        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5253
5254        app.makeActive(thread, mProcessStats);
5255        app.curAdj = app.setAdj = -100;
5256        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5257        app.forcingToForeground = null;
5258        updateProcessForegroundLocked(app, false, false);
5259        app.hasShownUi = false;
5260        app.debugging = false;
5261        app.cached = false;
5262
5263        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5264
5265        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5266        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5267
5268        if (!normalMode) {
5269            Slog.i(TAG, "Launching preboot mode app: " + app);
5270        }
5271
5272        if (localLOGV) Slog.v(
5273            TAG, "New app record " + app
5274            + " thread=" + thread.asBinder() + " pid=" + pid);
5275        try {
5276            int testMode = IApplicationThread.DEBUG_OFF;
5277            if (mDebugApp != null && mDebugApp.equals(processName)) {
5278                testMode = mWaitForDebugger
5279                    ? IApplicationThread.DEBUG_WAIT
5280                    : IApplicationThread.DEBUG_ON;
5281                app.debugging = true;
5282                if (mDebugTransient) {
5283                    mDebugApp = mOrigDebugApp;
5284                    mWaitForDebugger = mOrigWaitForDebugger;
5285                }
5286            }
5287            String profileFile = app.instrumentationProfileFile;
5288            ParcelFileDescriptor profileFd = null;
5289            boolean profileAutoStop = false;
5290            if (mProfileApp != null && mProfileApp.equals(processName)) {
5291                mProfileProc = app;
5292                profileFile = mProfileFile;
5293                profileFd = mProfileFd;
5294                profileAutoStop = mAutoStopProfiler;
5295            }
5296            boolean enableOpenGlTrace = false;
5297            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5298                enableOpenGlTrace = true;
5299                mOpenGlTraceApp = null;
5300            }
5301
5302            // If the app is being launched for restore or full backup, set it up specially
5303            boolean isRestrictedBackupMode = false;
5304            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5305                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5306                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5307                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5308            }
5309
5310            ensurePackageDexOpt(app.instrumentationInfo != null
5311                    ? app.instrumentationInfo.packageName
5312                    : app.info.packageName);
5313            if (app.instrumentationClass != null) {
5314                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5315            }
5316            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5317                    + processName + " with config " + mConfiguration);
5318            ApplicationInfo appInfo = app.instrumentationInfo != null
5319                    ? app.instrumentationInfo : app.info;
5320            app.compat = compatibilityInfoForPackageLocked(appInfo);
5321            if (profileFd != null) {
5322                profileFd = profileFd.dup();
5323            }
5324            thread.bindApplication(processName, appInfo, providers,
5325                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5326                    app.instrumentationArguments, app.instrumentationWatcher,
5327                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5328                    isRestrictedBackupMode || !normalMode, app.persistent,
5329                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5330                    mCoreSettingsObserver.getCoreSettingsLocked());
5331            updateLruProcessLocked(app, false, null);
5332            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5333        } catch (Exception e) {
5334            // todo: Yikes!  What should we do?  For now we will try to
5335            // start another process, but that could easily get us in
5336            // an infinite loop of restarting processes...
5337            Slog.w(TAG, "Exception thrown during bind!", e);
5338
5339            app.resetPackageList(mProcessStats);
5340            app.unlinkDeathRecipient();
5341            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5342            return false;
5343        }
5344
5345        // Remove this record from the list of starting applications.
5346        mPersistentStartingProcesses.remove(app);
5347        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5348                "Attach application locked removing on hold: " + app);
5349        mProcessesOnHold.remove(app);
5350
5351        boolean badApp = false;
5352        boolean didSomething = false;
5353
5354        // See if the top visible activity is waiting to run in this process...
5355        if (normalMode) {
5356            try {
5357                if (mStackSupervisor.attachApplicationLocked(app)) {
5358                    didSomething = true;
5359                }
5360            } catch (Exception e) {
5361                badApp = true;
5362            }
5363        }
5364
5365        // Find any services that should be running in this process...
5366        if (!badApp) {
5367            try {
5368                didSomething |= mServices.attachApplicationLocked(app, processName);
5369            } catch (Exception e) {
5370                badApp = true;
5371            }
5372        }
5373
5374        // Check if a next-broadcast receiver is in this process...
5375        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5376            try {
5377                didSomething |= sendPendingBroadcastsLocked(app);
5378            } catch (Exception e) {
5379                // If the app died trying to launch the receiver we declare it 'bad'
5380                badApp = true;
5381            }
5382        }
5383
5384        // Check whether the next backup agent is in this process...
5385        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5386            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5387            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5388            try {
5389                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5390                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5391                        mBackupTarget.backupMode);
5392            } catch (Exception e) {
5393                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5394                e.printStackTrace();
5395            }
5396        }
5397
5398        if (badApp) {
5399            // todo: Also need to kill application to deal with all
5400            // kinds of exceptions.
5401            handleAppDiedLocked(app, false, true);
5402            return false;
5403        }
5404
5405        if (!didSomething) {
5406            updateOomAdjLocked();
5407        }
5408
5409        return true;
5410    }
5411
5412    @Override
5413    public final void attachApplication(IApplicationThread thread) {
5414        synchronized (this) {
5415            int callingPid = Binder.getCallingPid();
5416            final long origId = Binder.clearCallingIdentity();
5417            attachApplicationLocked(thread, callingPid);
5418            Binder.restoreCallingIdentity(origId);
5419        }
5420    }
5421
5422    @Override
5423    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5424        final long origId = Binder.clearCallingIdentity();
5425        synchronized (this) {
5426            ActivityStack stack = ActivityRecord.getStackLocked(token);
5427            if (stack != null) {
5428                ActivityRecord r =
5429                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5430                if (stopProfiling) {
5431                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5432                        try {
5433                            mProfileFd.close();
5434                        } catch (IOException e) {
5435                        }
5436                        clearProfilerLocked();
5437                    }
5438                }
5439            }
5440        }
5441        Binder.restoreCallingIdentity(origId);
5442    }
5443
5444    void enableScreenAfterBoot() {
5445        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5446                SystemClock.uptimeMillis());
5447        mWindowManager.enableScreenAfterBoot();
5448
5449        synchronized (this) {
5450            updateEventDispatchingLocked();
5451        }
5452    }
5453
5454    @Override
5455    public void showBootMessage(final CharSequence msg, final boolean always) {
5456        enforceNotIsolatedCaller("showBootMessage");
5457        mWindowManager.showBootMessage(msg, always);
5458    }
5459
5460    @Override
5461    public void dismissKeyguardOnNextActivity() {
5462        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5463        final long token = Binder.clearCallingIdentity();
5464        try {
5465            synchronized (this) {
5466                if (DEBUG_LOCKSCREEN) logLockScreen("");
5467                if (mLockScreenShown) {
5468                    mLockScreenShown = false;
5469                    comeOutOfSleepIfNeededLocked();
5470                }
5471                mStackSupervisor.setDismissKeyguard(true);
5472            }
5473        } finally {
5474            Binder.restoreCallingIdentity(token);
5475        }
5476    }
5477
5478    final void finishBooting() {
5479        // Register receivers to handle package update events
5480        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5481
5482        synchronized (this) {
5483            // Ensure that any processes we had put on hold are now started
5484            // up.
5485            final int NP = mProcessesOnHold.size();
5486            if (NP > 0) {
5487                ArrayList<ProcessRecord> procs =
5488                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5489                for (int ip=0; ip<NP; ip++) {
5490                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5491                            + procs.get(ip));
5492                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5493                }
5494            }
5495
5496            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5497                // Start looking for apps that are abusing wake locks.
5498                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5499                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5500                // Tell anyone interested that we are done booting!
5501                SystemProperties.set("sys.boot_completed", "1");
5502                SystemProperties.set("dev.bootcomplete", "1");
5503                for (int i=0; i<mStartedUsers.size(); i++) {
5504                    UserStartedState uss = mStartedUsers.valueAt(i);
5505                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5506                        uss.mState = UserStartedState.STATE_RUNNING;
5507                        final int userId = mStartedUsers.keyAt(i);
5508                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5509                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5510                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5511                        broadcastIntentLocked(null, null, intent, null,
5512                                new IIntentReceiver.Stub() {
5513                                    @Override
5514                                    public void performReceive(Intent intent, int resultCode,
5515                                            String data, Bundle extras, boolean ordered,
5516                                            boolean sticky, int sendingUser) {
5517                                        synchronized (ActivityManagerService.this) {
5518                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5519                                                    true, false);
5520                                        }
5521                                    }
5522                                },
5523                                0, null, null,
5524                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5525                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5526                                userId);
5527                    }
5528                }
5529                scheduleStartProfilesLocked();
5530            }
5531        }
5532    }
5533
5534    final void ensureBootCompleted() {
5535        boolean booting;
5536        boolean enableScreen;
5537        synchronized (this) {
5538            booting = mBooting;
5539            mBooting = false;
5540            enableScreen = !mBooted;
5541            mBooted = true;
5542        }
5543
5544        if (booting) {
5545            finishBooting();
5546        }
5547
5548        if (enableScreen) {
5549            enableScreenAfterBoot();
5550        }
5551    }
5552
5553    @Override
5554    public final void activityResumed(IBinder token) {
5555        final long origId = Binder.clearCallingIdentity();
5556        synchronized(this) {
5557            ActivityStack stack = ActivityRecord.getStackLocked(token);
5558            if (stack != null) {
5559                ActivityRecord.activityResumedLocked(token);
5560            }
5561        }
5562        Binder.restoreCallingIdentity(origId);
5563    }
5564
5565    @Override
5566    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5567        final long origId = Binder.clearCallingIdentity();
5568        synchronized(this) {
5569            ActivityStack stack = ActivityRecord.getStackLocked(token);
5570            if (stack != null) {
5571                stack.activityPausedLocked(token, false, persistentState);
5572            }
5573        }
5574        Binder.restoreCallingIdentity(origId);
5575    }
5576
5577    @Override
5578    public final void activityStopped(IBinder token, Bundle icicle,
5579            PersistableBundle persistentState, CharSequence description) {
5580        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5581
5582        // Refuse possible leaked file descriptors
5583        if (icicle != null && icicle.hasFileDescriptors()) {
5584            throw new IllegalArgumentException("File descriptors passed in Bundle");
5585        }
5586
5587        final long origId = Binder.clearCallingIdentity();
5588
5589        synchronized (this) {
5590            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5591            if (r != null) {
5592                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5593            }
5594        }
5595
5596        trimApplications();
5597
5598        Binder.restoreCallingIdentity(origId);
5599    }
5600
5601    @Override
5602    public final void activityDestroyed(IBinder token) {
5603        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5604        synchronized (this) {
5605            ActivityStack stack = ActivityRecord.getStackLocked(token);
5606            if (stack != null) {
5607                stack.activityDestroyedLocked(token);
5608            }
5609        }
5610    }
5611
5612    @Override
5613    public final void mediaResourcesReleased(IBinder token) {
5614        final long origId = Binder.clearCallingIdentity();
5615        try {
5616            synchronized (this) {
5617                ActivityStack stack = ActivityRecord.getStackLocked(token);
5618                if (stack != null) {
5619                    stack.mediaResourcesReleased(token);
5620                }
5621            }
5622        } finally {
5623            Binder.restoreCallingIdentity(origId);
5624        }
5625    }
5626
5627    @Override
5628    public String getCallingPackage(IBinder token) {
5629        synchronized (this) {
5630            ActivityRecord r = getCallingRecordLocked(token);
5631            return r != null ? r.info.packageName : null;
5632        }
5633    }
5634
5635    @Override
5636    public ComponentName getCallingActivity(IBinder token) {
5637        synchronized (this) {
5638            ActivityRecord r = getCallingRecordLocked(token);
5639            return r != null ? r.intent.getComponent() : null;
5640        }
5641    }
5642
5643    private ActivityRecord getCallingRecordLocked(IBinder token) {
5644        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5645        if (r == null) {
5646            return null;
5647        }
5648        return r.resultTo;
5649    }
5650
5651    @Override
5652    public ComponentName getActivityClassForToken(IBinder token) {
5653        synchronized(this) {
5654            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5655            if (r == null) {
5656                return null;
5657            }
5658            return r.intent.getComponent();
5659        }
5660    }
5661
5662    @Override
5663    public String getPackageForToken(IBinder token) {
5664        synchronized(this) {
5665            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5666            if (r == null) {
5667                return null;
5668            }
5669            return r.packageName;
5670        }
5671    }
5672
5673    @Override
5674    public IIntentSender getIntentSender(int type,
5675            String packageName, IBinder token, String resultWho,
5676            int requestCode, Intent[] intents, String[] resolvedTypes,
5677            int flags, Bundle options, int userId) {
5678        enforceNotIsolatedCaller("getIntentSender");
5679        // Refuse possible leaked file descriptors
5680        if (intents != null) {
5681            if (intents.length < 1) {
5682                throw new IllegalArgumentException("Intents array length must be >= 1");
5683            }
5684            for (int i=0; i<intents.length; i++) {
5685                Intent intent = intents[i];
5686                if (intent != null) {
5687                    if (intent.hasFileDescriptors()) {
5688                        throw new IllegalArgumentException("File descriptors passed in Intent");
5689                    }
5690                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5691                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5692                        throw new IllegalArgumentException(
5693                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5694                    }
5695                    intents[i] = new Intent(intent);
5696                }
5697            }
5698            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5699                throw new IllegalArgumentException(
5700                        "Intent array length does not match resolvedTypes length");
5701            }
5702        }
5703        if (options != null) {
5704            if (options.hasFileDescriptors()) {
5705                throw new IllegalArgumentException("File descriptors passed in options");
5706            }
5707        }
5708
5709        synchronized(this) {
5710            int callingUid = Binder.getCallingUid();
5711            int origUserId = userId;
5712            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5713                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5714                    "getIntentSender", null);
5715            if (origUserId == UserHandle.USER_CURRENT) {
5716                // We don't want to evaluate this until the pending intent is
5717                // actually executed.  However, we do want to always do the
5718                // security checking for it above.
5719                userId = UserHandle.USER_CURRENT;
5720            }
5721            try {
5722                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5723                    int uid = AppGlobals.getPackageManager()
5724                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5725                    if (!UserHandle.isSameApp(callingUid, uid)) {
5726                        String msg = "Permission Denial: getIntentSender() from pid="
5727                            + Binder.getCallingPid()
5728                            + ", uid=" + Binder.getCallingUid()
5729                            + ", (need uid=" + uid + ")"
5730                            + " is not allowed to send as package " + packageName;
5731                        Slog.w(TAG, msg);
5732                        throw new SecurityException(msg);
5733                    }
5734                }
5735
5736                return getIntentSenderLocked(type, packageName, callingUid, userId,
5737                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5738
5739            } catch (RemoteException e) {
5740                throw new SecurityException(e);
5741            }
5742        }
5743    }
5744
5745    IIntentSender getIntentSenderLocked(int type, String packageName,
5746            int callingUid, int userId, IBinder token, String resultWho,
5747            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5748            Bundle options) {
5749        if (DEBUG_MU)
5750            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5751        ActivityRecord activity = null;
5752        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5753            activity = ActivityRecord.isInStackLocked(token);
5754            if (activity == null) {
5755                return null;
5756            }
5757            if (activity.finishing) {
5758                return null;
5759            }
5760        }
5761
5762        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5763        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5764        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5765        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5766                |PendingIntent.FLAG_UPDATE_CURRENT);
5767
5768        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5769                type, packageName, activity, resultWho,
5770                requestCode, intents, resolvedTypes, flags, options, userId);
5771        WeakReference<PendingIntentRecord> ref;
5772        ref = mIntentSenderRecords.get(key);
5773        PendingIntentRecord rec = ref != null ? ref.get() : null;
5774        if (rec != null) {
5775            if (!cancelCurrent) {
5776                if (updateCurrent) {
5777                    if (rec.key.requestIntent != null) {
5778                        rec.key.requestIntent.replaceExtras(intents != null ?
5779                                intents[intents.length - 1] : null);
5780                    }
5781                    if (intents != null) {
5782                        intents[intents.length-1] = rec.key.requestIntent;
5783                        rec.key.allIntents = intents;
5784                        rec.key.allResolvedTypes = resolvedTypes;
5785                    } else {
5786                        rec.key.allIntents = null;
5787                        rec.key.allResolvedTypes = null;
5788                    }
5789                }
5790                return rec;
5791            }
5792            rec.canceled = true;
5793            mIntentSenderRecords.remove(key);
5794        }
5795        if (noCreate) {
5796            return rec;
5797        }
5798        rec = new PendingIntentRecord(this, key, callingUid);
5799        mIntentSenderRecords.put(key, rec.ref);
5800        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5801            if (activity.pendingResults == null) {
5802                activity.pendingResults
5803                        = new HashSet<WeakReference<PendingIntentRecord>>();
5804            }
5805            activity.pendingResults.add(rec.ref);
5806        }
5807        return rec;
5808    }
5809
5810    @Override
5811    public void cancelIntentSender(IIntentSender sender) {
5812        if (!(sender instanceof PendingIntentRecord)) {
5813            return;
5814        }
5815        synchronized(this) {
5816            PendingIntentRecord rec = (PendingIntentRecord)sender;
5817            try {
5818                int uid = AppGlobals.getPackageManager()
5819                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5820                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5821                    String msg = "Permission Denial: cancelIntentSender() from pid="
5822                        + Binder.getCallingPid()
5823                        + ", uid=" + Binder.getCallingUid()
5824                        + " is not allowed to cancel packges "
5825                        + rec.key.packageName;
5826                    Slog.w(TAG, msg);
5827                    throw new SecurityException(msg);
5828                }
5829            } catch (RemoteException e) {
5830                throw new SecurityException(e);
5831            }
5832            cancelIntentSenderLocked(rec, true);
5833        }
5834    }
5835
5836    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5837        rec.canceled = true;
5838        mIntentSenderRecords.remove(rec.key);
5839        if (cleanActivity && rec.key.activity != null) {
5840            rec.key.activity.pendingResults.remove(rec.ref);
5841        }
5842    }
5843
5844    @Override
5845    public String getPackageForIntentSender(IIntentSender pendingResult) {
5846        if (!(pendingResult instanceof PendingIntentRecord)) {
5847            return null;
5848        }
5849        try {
5850            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5851            return res.key.packageName;
5852        } catch (ClassCastException e) {
5853        }
5854        return null;
5855    }
5856
5857    @Override
5858    public int getUidForIntentSender(IIntentSender sender) {
5859        if (sender instanceof PendingIntentRecord) {
5860            try {
5861                PendingIntentRecord res = (PendingIntentRecord)sender;
5862                return res.uid;
5863            } catch (ClassCastException e) {
5864            }
5865        }
5866        return -1;
5867    }
5868
5869    @Override
5870    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5871        if (!(pendingResult instanceof PendingIntentRecord)) {
5872            return false;
5873        }
5874        try {
5875            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5876            if (res.key.allIntents == null) {
5877                return false;
5878            }
5879            for (int i=0; i<res.key.allIntents.length; i++) {
5880                Intent intent = res.key.allIntents[i];
5881                if (intent.getPackage() != null && intent.getComponent() != null) {
5882                    return false;
5883                }
5884            }
5885            return true;
5886        } catch (ClassCastException e) {
5887        }
5888        return false;
5889    }
5890
5891    @Override
5892    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5893        if (!(pendingResult instanceof PendingIntentRecord)) {
5894            return false;
5895        }
5896        try {
5897            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5898            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5899                return true;
5900            }
5901            return false;
5902        } catch (ClassCastException e) {
5903        }
5904        return false;
5905    }
5906
5907    @Override
5908    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5909        if (!(pendingResult instanceof PendingIntentRecord)) {
5910            return null;
5911        }
5912        try {
5913            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5914            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5915        } catch (ClassCastException e) {
5916        }
5917        return null;
5918    }
5919
5920    @Override
5921    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5922        if (!(pendingResult instanceof PendingIntentRecord)) {
5923            return null;
5924        }
5925        try {
5926            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5927            Intent intent = res.key.requestIntent;
5928            if (intent != null) {
5929                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5930                        || res.lastTagPrefix.equals(prefix))) {
5931                    return res.lastTag;
5932                }
5933                res.lastTagPrefix = prefix;
5934                StringBuilder sb = new StringBuilder(128);
5935                if (prefix != null) {
5936                    sb.append(prefix);
5937                }
5938                if (intent.getAction() != null) {
5939                    sb.append(intent.getAction());
5940                } else if (intent.getComponent() != null) {
5941                    intent.getComponent().appendShortString(sb);
5942                } else {
5943                    sb.append("?");
5944                }
5945                return res.lastTag = sb.toString();
5946            }
5947        } catch (ClassCastException e) {
5948        }
5949        return null;
5950    }
5951
5952    @Override
5953    public void setProcessLimit(int max) {
5954        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5955                "setProcessLimit()");
5956        synchronized (this) {
5957            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5958            mProcessLimitOverride = max;
5959        }
5960        trimApplications();
5961    }
5962
5963    @Override
5964    public int getProcessLimit() {
5965        synchronized (this) {
5966            return mProcessLimitOverride;
5967        }
5968    }
5969
5970    void foregroundTokenDied(ForegroundToken token) {
5971        synchronized (ActivityManagerService.this) {
5972            synchronized (mPidsSelfLocked) {
5973                ForegroundToken cur
5974                    = mForegroundProcesses.get(token.pid);
5975                if (cur != token) {
5976                    return;
5977                }
5978                mForegroundProcesses.remove(token.pid);
5979                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5980                if (pr == null) {
5981                    return;
5982                }
5983                pr.forcingToForeground = null;
5984                updateProcessForegroundLocked(pr, false, false);
5985            }
5986            updateOomAdjLocked();
5987        }
5988    }
5989
5990    @Override
5991    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5992        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5993                "setProcessForeground()");
5994        synchronized(this) {
5995            boolean changed = false;
5996
5997            synchronized (mPidsSelfLocked) {
5998                ProcessRecord pr = mPidsSelfLocked.get(pid);
5999                if (pr == null && isForeground) {
6000                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6001                    return;
6002                }
6003                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6004                if (oldToken != null) {
6005                    oldToken.token.unlinkToDeath(oldToken, 0);
6006                    mForegroundProcesses.remove(pid);
6007                    if (pr != null) {
6008                        pr.forcingToForeground = null;
6009                    }
6010                    changed = true;
6011                }
6012                if (isForeground && token != null) {
6013                    ForegroundToken newToken = new ForegroundToken() {
6014                        @Override
6015                        public void binderDied() {
6016                            foregroundTokenDied(this);
6017                        }
6018                    };
6019                    newToken.pid = pid;
6020                    newToken.token = token;
6021                    try {
6022                        token.linkToDeath(newToken, 0);
6023                        mForegroundProcesses.put(pid, newToken);
6024                        pr.forcingToForeground = token;
6025                        changed = true;
6026                    } catch (RemoteException e) {
6027                        // If the process died while doing this, we will later
6028                        // do the cleanup with the process death link.
6029                    }
6030                }
6031            }
6032
6033            if (changed) {
6034                updateOomAdjLocked();
6035            }
6036        }
6037    }
6038
6039    // =========================================================
6040    // PERMISSIONS
6041    // =========================================================
6042
6043    static class PermissionController extends IPermissionController.Stub {
6044        ActivityManagerService mActivityManagerService;
6045        PermissionController(ActivityManagerService activityManagerService) {
6046            mActivityManagerService = activityManagerService;
6047        }
6048
6049        @Override
6050        public boolean checkPermission(String permission, int pid, int uid) {
6051            return mActivityManagerService.checkPermission(permission, pid,
6052                    uid) == PackageManager.PERMISSION_GRANTED;
6053        }
6054    }
6055
6056    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6057        @Override
6058        public int checkComponentPermission(String permission, int pid, int uid,
6059                int owningUid, boolean exported) {
6060            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6061                    owningUid, exported);
6062        }
6063
6064        @Override
6065        public Object getAMSLock() {
6066            return ActivityManagerService.this;
6067        }
6068    }
6069
6070    /**
6071     * This can be called with or without the global lock held.
6072     */
6073    int checkComponentPermission(String permission, int pid, int uid,
6074            int owningUid, boolean exported) {
6075        // We might be performing an operation on behalf of an indirect binder
6076        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6077        // client identity accordingly before proceeding.
6078        Identity tlsIdentity = sCallerIdentity.get();
6079        if (tlsIdentity != null) {
6080            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6081                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6082            uid = tlsIdentity.uid;
6083            pid = tlsIdentity.pid;
6084        }
6085
6086        if (pid == MY_PID) {
6087            return PackageManager.PERMISSION_GRANTED;
6088        }
6089
6090        return ActivityManager.checkComponentPermission(permission, uid,
6091                owningUid, exported);
6092    }
6093
6094    /**
6095     * As the only public entry point for permissions checking, this method
6096     * can enforce the semantic that requesting a check on a null global
6097     * permission is automatically denied.  (Internally a null permission
6098     * string is used when calling {@link #checkComponentPermission} in cases
6099     * when only uid-based security is needed.)
6100     *
6101     * This can be called with or without the global lock held.
6102     */
6103    @Override
6104    public int checkPermission(String permission, int pid, int uid) {
6105        if (permission == null) {
6106            return PackageManager.PERMISSION_DENIED;
6107        }
6108        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6109    }
6110
6111    /**
6112     * Binder IPC calls go through the public entry point.
6113     * This can be called with or without the global lock held.
6114     */
6115    int checkCallingPermission(String permission) {
6116        return checkPermission(permission,
6117                Binder.getCallingPid(),
6118                UserHandle.getAppId(Binder.getCallingUid()));
6119    }
6120
6121    /**
6122     * This can be called with or without the global lock held.
6123     */
6124    void enforceCallingPermission(String permission, String func) {
6125        if (checkCallingPermission(permission)
6126                == PackageManager.PERMISSION_GRANTED) {
6127            return;
6128        }
6129
6130        String msg = "Permission Denial: " + func + " from pid="
6131                + Binder.getCallingPid()
6132                + ", uid=" + Binder.getCallingUid()
6133                + " requires " + permission;
6134        Slog.w(TAG, msg);
6135        throw new SecurityException(msg);
6136    }
6137
6138    /**
6139     * Determine if UID is holding permissions required to access {@link Uri} in
6140     * the given {@link ProviderInfo}. Final permission checking is always done
6141     * in {@link ContentProvider}.
6142     */
6143    private final boolean checkHoldingPermissionsLocked(
6144            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6145        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6146                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6147        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6148            return false;
6149        }
6150        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6151    }
6152
6153    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6154            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6155        if (pi.applicationInfo.uid == uid) {
6156            return true;
6157        } else if (!pi.exported) {
6158            return false;
6159        }
6160
6161        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6162        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6163        try {
6164            // check if target holds top-level <provider> permissions
6165            if (!readMet && pi.readPermission != null && considerUidPermissions
6166                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6167                readMet = true;
6168            }
6169            if (!writeMet && pi.writePermission != null && considerUidPermissions
6170                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6171                writeMet = true;
6172            }
6173
6174            // track if unprotected read/write is allowed; any denied
6175            // <path-permission> below removes this ability
6176            boolean allowDefaultRead = pi.readPermission == null;
6177            boolean allowDefaultWrite = pi.writePermission == null;
6178
6179            // check if target holds any <path-permission> that match uri
6180            final PathPermission[] pps = pi.pathPermissions;
6181            if (pps != null) {
6182                final String path = grantUri.uri.getPath();
6183                int i = pps.length;
6184                while (i > 0 && (!readMet || !writeMet)) {
6185                    i--;
6186                    PathPermission pp = pps[i];
6187                    if (pp.match(path)) {
6188                        if (!readMet) {
6189                            final String pprperm = pp.getReadPermission();
6190                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6191                                    + pprperm + " for " + pp.getPath()
6192                                    + ": match=" + pp.match(path)
6193                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6194                            if (pprperm != null) {
6195                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6196                                        == PERMISSION_GRANTED) {
6197                                    readMet = true;
6198                                } else {
6199                                    allowDefaultRead = false;
6200                                }
6201                            }
6202                        }
6203                        if (!writeMet) {
6204                            final String ppwperm = pp.getWritePermission();
6205                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6206                                    + ppwperm + " for " + pp.getPath()
6207                                    + ": match=" + pp.match(path)
6208                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6209                            if (ppwperm != null) {
6210                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6211                                        == PERMISSION_GRANTED) {
6212                                    writeMet = true;
6213                                } else {
6214                                    allowDefaultWrite = false;
6215                                }
6216                            }
6217                        }
6218                    }
6219                }
6220            }
6221
6222            // grant unprotected <provider> read/write, if not blocked by
6223            // <path-permission> above
6224            if (allowDefaultRead) readMet = true;
6225            if (allowDefaultWrite) writeMet = true;
6226
6227        } catch (RemoteException e) {
6228            return false;
6229        }
6230
6231        return readMet && writeMet;
6232    }
6233
6234    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6235        ProviderInfo pi = null;
6236        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6237        if (cpr != null) {
6238            pi = cpr.info;
6239        } else {
6240            try {
6241                pi = AppGlobals.getPackageManager().resolveContentProvider(
6242                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6243            } catch (RemoteException ex) {
6244            }
6245        }
6246        return pi;
6247    }
6248
6249    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6250        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6251        if (targetUris != null) {
6252            return targetUris.get(grantUri);
6253        }
6254        return null;
6255    }
6256
6257    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6258            String targetPkg, int targetUid, GrantUri grantUri) {
6259        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6260        if (targetUris == null) {
6261            targetUris = Maps.newArrayMap();
6262            mGrantedUriPermissions.put(targetUid, targetUris);
6263        }
6264
6265        UriPermission perm = targetUris.get(grantUri);
6266        if (perm == null) {
6267            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6268            targetUris.put(grantUri, perm);
6269        }
6270
6271        return perm;
6272    }
6273
6274    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6275            final int modeFlags) {
6276        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6277        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6278                : UriPermission.STRENGTH_OWNED;
6279
6280        // Root gets to do everything.
6281        if (uid == 0) {
6282            return true;
6283        }
6284
6285        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6286        if (perms == null) return false;
6287
6288        // First look for exact match
6289        final UriPermission exactPerm = perms.get(grantUri);
6290        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6291            return true;
6292        }
6293
6294        // No exact match, look for prefixes
6295        final int N = perms.size();
6296        for (int i = 0; i < N; i++) {
6297            final UriPermission perm = perms.valueAt(i);
6298            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6299                    && perm.getStrength(modeFlags) >= minStrength) {
6300                return true;
6301            }
6302        }
6303
6304        return false;
6305    }
6306
6307    @Override
6308    public int checkUriPermission(Uri uri, int pid, int uid,
6309            final int modeFlags, int userId) {
6310        enforceNotIsolatedCaller("checkUriPermission");
6311
6312        // Another redirected-binder-call permissions check as in
6313        // {@link checkComponentPermission}.
6314        Identity tlsIdentity = sCallerIdentity.get();
6315        if (tlsIdentity != null) {
6316            uid = tlsIdentity.uid;
6317            pid = tlsIdentity.pid;
6318        }
6319
6320        // Our own process gets to do everything.
6321        if (pid == MY_PID) {
6322            return PackageManager.PERMISSION_GRANTED;
6323        }
6324        synchronized (this) {
6325            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6326                    ? PackageManager.PERMISSION_GRANTED
6327                    : PackageManager.PERMISSION_DENIED;
6328        }
6329    }
6330
6331    /**
6332     * Check if the targetPkg can be granted permission to access uri by
6333     * the callingUid using the given modeFlags.  Throws a security exception
6334     * if callingUid is not allowed to do this.  Returns the uid of the target
6335     * if the URI permission grant should be performed; returns -1 if it is not
6336     * needed (for example targetPkg already has permission to access the URI).
6337     * If you already know the uid of the target, you can supply it in
6338     * lastTargetUid else set that to -1.
6339     */
6340    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6341            final int modeFlags, int lastTargetUid) {
6342        if (!Intent.isAccessUriMode(modeFlags)) {
6343            return -1;
6344        }
6345
6346        if (targetPkg != null) {
6347            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6348                    "Checking grant " + targetPkg + " permission to " + grantUri);
6349        }
6350
6351        final IPackageManager pm = AppGlobals.getPackageManager();
6352
6353        // If this is not a content: uri, we can't do anything with it.
6354        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6355            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6356                    "Can't grant URI permission for non-content URI: " + grantUri);
6357            return -1;
6358        }
6359
6360        final String authority = grantUri.uri.getAuthority();
6361        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6362        if (pi == null) {
6363            Slog.w(TAG, "No content provider found for permission check: " +
6364                    grantUri.uri.toSafeString());
6365            return -1;
6366        }
6367
6368        int targetUid = lastTargetUid;
6369        if (targetUid < 0 && targetPkg != null) {
6370            try {
6371                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6372                if (targetUid < 0) {
6373                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6374                            "Can't grant URI permission no uid for: " + targetPkg);
6375                    return -1;
6376                }
6377            } catch (RemoteException ex) {
6378                return -1;
6379            }
6380        }
6381
6382        if (targetUid >= 0) {
6383            // First...  does the target actually need this permission?
6384            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6385                // No need to grant the target this permission.
6386                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6387                        "Target " + targetPkg + " already has full permission to " + grantUri);
6388                return -1;
6389            }
6390        } else {
6391            // First...  there is no target package, so can anyone access it?
6392            boolean allowed = pi.exported;
6393            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6394                if (pi.readPermission != null) {
6395                    allowed = false;
6396                }
6397            }
6398            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6399                if (pi.writePermission != null) {
6400                    allowed = false;
6401                }
6402            }
6403            if (allowed) {
6404                return -1;
6405            }
6406        }
6407
6408        /* There is a special cross user grant if:
6409         * - The target is on another user.
6410         * - Apps on the current user can access the uri without any uid permissions.
6411         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6412         * grant uri permissions.
6413         */
6414        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6415                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6416                modeFlags, false /*without considering the uid permissions*/);
6417
6418        // Second...  is the provider allowing granting of URI permissions?
6419        if (!specialCrossUserGrant) {
6420            if (!pi.grantUriPermissions) {
6421                throw new SecurityException("Provider " + pi.packageName
6422                        + "/" + pi.name
6423                        + " does not allow granting of Uri permissions (uri "
6424                        + grantUri + ")");
6425            }
6426            if (pi.uriPermissionPatterns != null) {
6427                final int N = pi.uriPermissionPatterns.length;
6428                boolean allowed = false;
6429                for (int i=0; i<N; i++) {
6430                    if (pi.uriPermissionPatterns[i] != null
6431                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6432                        allowed = true;
6433                        break;
6434                    }
6435                }
6436                if (!allowed) {
6437                    throw new SecurityException("Provider " + pi.packageName
6438                            + "/" + pi.name
6439                            + " does not allow granting of permission to path of Uri "
6440                            + grantUri);
6441                }
6442            }
6443        }
6444
6445        // Third...  does the caller itself have permission to access
6446        // this uri?
6447        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6448            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6449                // Require they hold a strong enough Uri permission
6450                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6451                    throw new SecurityException("Uid " + callingUid
6452                            + " does not have permission to uri " + grantUri);
6453                }
6454            }
6455        }
6456        return targetUid;
6457    }
6458
6459    @Override
6460    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6461            final int modeFlags, int userId) {
6462        enforceNotIsolatedCaller("checkGrantUriPermission");
6463        synchronized(this) {
6464            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6465                    new GrantUri(userId, uri, false), modeFlags, -1);
6466        }
6467    }
6468
6469    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6470            final int modeFlags, UriPermissionOwner owner) {
6471        if (!Intent.isAccessUriMode(modeFlags)) {
6472            return;
6473        }
6474
6475        // So here we are: the caller has the assumed permission
6476        // to the uri, and the target doesn't.  Let's now give this to
6477        // the target.
6478
6479        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6480                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6481
6482        final String authority = grantUri.uri.getAuthority();
6483        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6484        if (pi == null) {
6485            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6486            return;
6487        }
6488
6489        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6490            grantUri.prefix = true;
6491        }
6492        final UriPermission perm = findOrCreateUriPermissionLocked(
6493                pi.packageName, targetPkg, targetUid, grantUri);
6494        perm.grantModes(modeFlags, owner);
6495    }
6496
6497    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6498            final int modeFlags, UriPermissionOwner owner) {
6499        if (targetPkg == null) {
6500            throw new NullPointerException("targetPkg");
6501        }
6502
6503        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6504                -1);
6505        if (targetUid < 0) {
6506            return;
6507        }
6508
6509        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6510                owner);
6511    }
6512
6513    static class NeededUriGrants extends ArrayList<GrantUri> {
6514        final String targetPkg;
6515        final int targetUid;
6516        final int flags;
6517
6518        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6519            this.targetPkg = targetPkg;
6520            this.targetUid = targetUid;
6521            this.flags = flags;
6522        }
6523    }
6524
6525    /**
6526     * Like checkGrantUriPermissionLocked, but takes an Intent.
6527     */
6528    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6529            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6530        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6531                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6532                + " clip=" + (intent != null ? intent.getClipData() : null)
6533                + " from " + intent + "; flags=0x"
6534                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6535
6536        if (targetPkg == null) {
6537            throw new NullPointerException("targetPkg");
6538        }
6539
6540        if (intent == null) {
6541            return null;
6542        }
6543        Uri data = intent.getData();
6544        ClipData clip = intent.getClipData();
6545        if (data == null && clip == null) {
6546            return null;
6547        }
6548        final IPackageManager pm = AppGlobals.getPackageManager();
6549        int targetUid;
6550        if (needed != null) {
6551            targetUid = needed.targetUid;
6552        } else {
6553            try {
6554                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6555            } catch (RemoteException ex) {
6556                return null;
6557            }
6558            if (targetUid < 0) {
6559                if (DEBUG_URI_PERMISSION) {
6560                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6561                            + " on user " + targetUserId);
6562                }
6563                return null;
6564            }
6565        }
6566        if (data != null) {
6567            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6568            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6569                    targetUid);
6570            if (targetUid > 0) {
6571                if (needed == null) {
6572                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6573                }
6574                needed.add(grantUri);
6575            }
6576        }
6577        if (clip != null) {
6578            for (int i=0; i<clip.getItemCount(); i++) {
6579                Uri uri = clip.getItemAt(i).getUri();
6580                if (uri != null) {
6581                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6582                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6583                            targetUid);
6584                    if (targetUid > 0) {
6585                        if (needed == null) {
6586                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6587                        }
6588                        needed.add(grantUri);
6589                    }
6590                } else {
6591                    Intent clipIntent = clip.getItemAt(i).getIntent();
6592                    if (clipIntent != null) {
6593                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6594                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6595                        if (newNeeded != null) {
6596                            needed = newNeeded;
6597                        }
6598                    }
6599                }
6600            }
6601        }
6602
6603        return needed;
6604    }
6605
6606    /**
6607     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6608     */
6609    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6610            UriPermissionOwner owner) {
6611        if (needed != null) {
6612            for (int i=0; i<needed.size(); i++) {
6613                GrantUri grantUri = needed.get(i);
6614                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6615                        grantUri, needed.flags, owner);
6616            }
6617        }
6618    }
6619
6620    void grantUriPermissionFromIntentLocked(int callingUid,
6621            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6622        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6623                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6624        if (needed == null) {
6625            return;
6626        }
6627
6628        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6629    }
6630
6631    @Override
6632    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6633            final int modeFlags, int userId) {
6634        enforceNotIsolatedCaller("grantUriPermission");
6635        GrantUri grantUri = new GrantUri(userId, uri, false);
6636        synchronized(this) {
6637            final ProcessRecord r = getRecordForAppLocked(caller);
6638            if (r == null) {
6639                throw new SecurityException("Unable to find app for caller "
6640                        + caller
6641                        + " when granting permission to uri " + grantUri);
6642            }
6643            if (targetPkg == null) {
6644                throw new IllegalArgumentException("null target");
6645            }
6646            if (grantUri == null) {
6647                throw new IllegalArgumentException("null uri");
6648            }
6649
6650            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6651                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6652                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6653                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6654
6655            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6656        }
6657    }
6658
6659    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6660        if (perm.modeFlags == 0) {
6661            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6662                    perm.targetUid);
6663            if (perms != null) {
6664                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6665                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6666
6667                perms.remove(perm.uri);
6668                if (perms.isEmpty()) {
6669                    mGrantedUriPermissions.remove(perm.targetUid);
6670                }
6671            }
6672        }
6673    }
6674
6675    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6676        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6677
6678        final IPackageManager pm = AppGlobals.getPackageManager();
6679        final String authority = grantUri.uri.getAuthority();
6680        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6681        if (pi == null) {
6682            Slog.w(TAG, "No content provider found for permission revoke: "
6683                    + grantUri.toSafeString());
6684            return;
6685        }
6686
6687        // Does the caller have this permission on the URI?
6688        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6689            // Right now, if you are not the original owner of the permission,
6690            // you are not allowed to revoke it.
6691            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6692                throw new SecurityException("Uid " + callingUid
6693                        + " does not have permission to uri " + grantUri);
6694            //}
6695        }
6696
6697        boolean persistChanged = false;
6698
6699        // Go through all of the permissions and remove any that match.
6700        int N = mGrantedUriPermissions.size();
6701        for (int i = 0; i < N; i++) {
6702            final int targetUid = mGrantedUriPermissions.keyAt(i);
6703            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6704
6705            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6706                final UriPermission perm = it.next();
6707                if (perm.uri.sourceUserId == grantUri.sourceUserId
6708                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6709                    if (DEBUG_URI_PERMISSION)
6710                        Slog.v(TAG,
6711                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6712                    persistChanged |= perm.revokeModes(
6713                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6714                    if (perm.modeFlags == 0) {
6715                        it.remove();
6716                    }
6717                }
6718            }
6719
6720            if (perms.isEmpty()) {
6721                mGrantedUriPermissions.remove(targetUid);
6722                N--;
6723                i--;
6724            }
6725        }
6726
6727        if (persistChanged) {
6728            schedulePersistUriGrants();
6729        }
6730    }
6731
6732    @Override
6733    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6734            int userId) {
6735        enforceNotIsolatedCaller("revokeUriPermission");
6736        synchronized(this) {
6737            final ProcessRecord r = getRecordForAppLocked(caller);
6738            if (r == null) {
6739                throw new SecurityException("Unable to find app for caller "
6740                        + caller
6741                        + " when revoking permission to uri " + uri);
6742            }
6743            if (uri == null) {
6744                Slog.w(TAG, "revokeUriPermission: null uri");
6745                return;
6746            }
6747
6748            if (!Intent.isAccessUriMode(modeFlags)) {
6749                return;
6750            }
6751
6752            final IPackageManager pm = AppGlobals.getPackageManager();
6753            final String authority = uri.getAuthority();
6754            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6755            if (pi == null) {
6756                Slog.w(TAG, "No content provider found for permission revoke: "
6757                        + uri.toSafeString());
6758                return;
6759            }
6760
6761            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6762        }
6763    }
6764
6765    /**
6766     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6767     * given package.
6768     *
6769     * @param packageName Package name to match, or {@code null} to apply to all
6770     *            packages.
6771     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6772     *            to all users.
6773     * @param persistable If persistable grants should be removed.
6774     */
6775    private void removeUriPermissionsForPackageLocked(
6776            String packageName, int userHandle, boolean persistable) {
6777        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6778            throw new IllegalArgumentException("Must narrow by either package or user");
6779        }
6780
6781        boolean persistChanged = false;
6782
6783        int N = mGrantedUriPermissions.size();
6784        for (int i = 0; i < N; i++) {
6785            final int targetUid = mGrantedUriPermissions.keyAt(i);
6786            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6787
6788            // Only inspect grants matching user
6789            if (userHandle == UserHandle.USER_ALL
6790                    || userHandle == UserHandle.getUserId(targetUid)) {
6791                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6792                    final UriPermission perm = it.next();
6793
6794                    // Only inspect grants matching package
6795                    if (packageName == null || perm.sourcePkg.equals(packageName)
6796                            || perm.targetPkg.equals(packageName)) {
6797                        persistChanged |= perm.revokeModes(
6798                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6799
6800                        // Only remove when no modes remain; any persisted grants
6801                        // will keep this alive.
6802                        if (perm.modeFlags == 0) {
6803                            it.remove();
6804                        }
6805                    }
6806                }
6807
6808                if (perms.isEmpty()) {
6809                    mGrantedUriPermissions.remove(targetUid);
6810                    N--;
6811                    i--;
6812                }
6813            }
6814        }
6815
6816        if (persistChanged) {
6817            schedulePersistUriGrants();
6818        }
6819    }
6820
6821    @Override
6822    public IBinder newUriPermissionOwner(String name) {
6823        enforceNotIsolatedCaller("newUriPermissionOwner");
6824        synchronized(this) {
6825            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6826            return owner.getExternalTokenLocked();
6827        }
6828    }
6829
6830    @Override
6831    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6832            final int modeFlags, int userId) {
6833        synchronized(this) {
6834            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6835            if (owner == null) {
6836                throw new IllegalArgumentException("Unknown owner: " + token);
6837            }
6838            if (fromUid != Binder.getCallingUid()) {
6839                if (Binder.getCallingUid() != Process.myUid()) {
6840                    // Only system code can grant URI permissions on behalf
6841                    // of other users.
6842                    throw new SecurityException("nice try");
6843                }
6844            }
6845            if (targetPkg == null) {
6846                throw new IllegalArgumentException("null target");
6847            }
6848            if (uri == null) {
6849                throw new IllegalArgumentException("null uri");
6850            }
6851
6852            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6853                    modeFlags, owner);
6854        }
6855    }
6856
6857    @Override
6858    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6859        synchronized(this) {
6860            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6861            if (owner == null) {
6862                throw new IllegalArgumentException("Unknown owner: " + token);
6863            }
6864
6865            if (uri == null) {
6866                owner.removeUriPermissionsLocked(mode);
6867            } else {
6868                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6869            }
6870        }
6871    }
6872
6873    private void schedulePersistUriGrants() {
6874        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6875            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6876                    10 * DateUtils.SECOND_IN_MILLIS);
6877        }
6878    }
6879
6880    private void writeGrantedUriPermissions() {
6881        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6882
6883        // Snapshot permissions so we can persist without lock
6884        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6885        synchronized (this) {
6886            final int size = mGrantedUriPermissions.size();
6887            for (int i = 0; i < size; i++) {
6888                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6889                for (UriPermission perm : perms.values()) {
6890                    if (perm.persistedModeFlags != 0) {
6891                        persist.add(perm.snapshot());
6892                    }
6893                }
6894            }
6895        }
6896
6897        FileOutputStream fos = null;
6898        try {
6899            fos = mGrantFile.startWrite();
6900
6901            XmlSerializer out = new FastXmlSerializer();
6902            out.setOutput(fos, "utf-8");
6903            out.startDocument(null, true);
6904            out.startTag(null, TAG_URI_GRANTS);
6905            for (UriPermission.Snapshot perm : persist) {
6906                out.startTag(null, TAG_URI_GRANT);
6907                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6908                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6909                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6910                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6911                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6912                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6913                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6914                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6915                out.endTag(null, TAG_URI_GRANT);
6916            }
6917            out.endTag(null, TAG_URI_GRANTS);
6918            out.endDocument();
6919
6920            mGrantFile.finishWrite(fos);
6921        } catch (IOException e) {
6922            if (fos != null) {
6923                mGrantFile.failWrite(fos);
6924            }
6925        }
6926    }
6927
6928    private void readGrantedUriPermissionsLocked() {
6929        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6930
6931        final long now = System.currentTimeMillis();
6932
6933        FileInputStream fis = null;
6934        try {
6935            fis = mGrantFile.openRead();
6936            final XmlPullParser in = Xml.newPullParser();
6937            in.setInput(fis, null);
6938
6939            int type;
6940            while ((type = in.next()) != END_DOCUMENT) {
6941                final String tag = in.getName();
6942                if (type == START_TAG) {
6943                    if (TAG_URI_GRANT.equals(tag)) {
6944                        final int sourceUserId;
6945                        final int targetUserId;
6946                        final int userHandle = readIntAttribute(in,
6947                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6948                        if (userHandle != UserHandle.USER_NULL) {
6949                            // For backwards compatibility.
6950                            sourceUserId = userHandle;
6951                            targetUserId = userHandle;
6952                        } else {
6953                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6954                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6955                        }
6956                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6957                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6958                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6959                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6960                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6961                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6962
6963                        // Sanity check that provider still belongs to source package
6964                        final ProviderInfo pi = getProviderInfoLocked(
6965                                uri.getAuthority(), sourceUserId);
6966                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6967                            int targetUid = -1;
6968                            try {
6969                                targetUid = AppGlobals.getPackageManager()
6970                                        .getPackageUid(targetPkg, targetUserId);
6971                            } catch (RemoteException e) {
6972                            }
6973                            if (targetUid != -1) {
6974                                final UriPermission perm = findOrCreateUriPermissionLocked(
6975                                        sourcePkg, targetPkg, targetUid,
6976                                        new GrantUri(sourceUserId, uri, prefix));
6977                                perm.initPersistedModes(modeFlags, createdTime);
6978                            }
6979                        } else {
6980                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6981                                    + " but instead found " + pi);
6982                        }
6983                    }
6984                }
6985            }
6986        } catch (FileNotFoundException e) {
6987            // Missing grants is okay
6988        } catch (IOException e) {
6989            Log.wtf(TAG, "Failed reading Uri grants", e);
6990        } catch (XmlPullParserException e) {
6991            Log.wtf(TAG, "Failed reading Uri grants", e);
6992        } finally {
6993            IoUtils.closeQuietly(fis);
6994        }
6995    }
6996
6997    @Override
6998    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6999        enforceNotIsolatedCaller("takePersistableUriPermission");
7000
7001        Preconditions.checkFlagsArgument(modeFlags,
7002                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7003
7004        synchronized (this) {
7005            final int callingUid = Binder.getCallingUid();
7006            boolean persistChanged = false;
7007            GrantUri grantUri = new GrantUri(userId, uri, false);
7008
7009            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7010                    new GrantUri(userId, uri, false));
7011            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7012                    new GrantUri(userId, uri, true));
7013
7014            final boolean exactValid = (exactPerm != null)
7015                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7016            final boolean prefixValid = (prefixPerm != null)
7017                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7018
7019            if (!(exactValid || prefixValid)) {
7020                throw new SecurityException("No persistable permission grants found for UID "
7021                        + callingUid + " and Uri " + grantUri.toSafeString());
7022            }
7023
7024            if (exactValid) {
7025                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7026            }
7027            if (prefixValid) {
7028                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7029            }
7030
7031            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7032
7033            if (persistChanged) {
7034                schedulePersistUriGrants();
7035            }
7036        }
7037    }
7038
7039    @Override
7040    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7041        enforceNotIsolatedCaller("releasePersistableUriPermission");
7042
7043        Preconditions.checkFlagsArgument(modeFlags,
7044                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7045
7046        synchronized (this) {
7047            final int callingUid = Binder.getCallingUid();
7048            boolean persistChanged = false;
7049
7050            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7051                    new GrantUri(userId, uri, false));
7052            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7053                    new GrantUri(userId, uri, true));
7054            if (exactPerm == null && prefixPerm == null) {
7055                throw new SecurityException("No permission grants found for UID " + callingUid
7056                        + " and Uri " + uri.toSafeString());
7057            }
7058
7059            if (exactPerm != null) {
7060                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7061                removeUriPermissionIfNeededLocked(exactPerm);
7062            }
7063            if (prefixPerm != null) {
7064                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7065                removeUriPermissionIfNeededLocked(prefixPerm);
7066            }
7067
7068            if (persistChanged) {
7069                schedulePersistUriGrants();
7070            }
7071        }
7072    }
7073
7074    /**
7075     * Prune any older {@link UriPermission} for the given UID until outstanding
7076     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7077     *
7078     * @return if any mutations occured that require persisting.
7079     */
7080    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7081        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7082        if (perms == null) return false;
7083        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7084
7085        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7086        for (UriPermission perm : perms.values()) {
7087            if (perm.persistedModeFlags != 0) {
7088                persisted.add(perm);
7089            }
7090        }
7091
7092        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7093        if (trimCount <= 0) return false;
7094
7095        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7096        for (int i = 0; i < trimCount; i++) {
7097            final UriPermission perm = persisted.get(i);
7098
7099            if (DEBUG_URI_PERMISSION) {
7100                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7101            }
7102
7103            perm.releasePersistableModes(~0);
7104            removeUriPermissionIfNeededLocked(perm);
7105        }
7106
7107        return true;
7108    }
7109
7110    @Override
7111    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7112            String packageName, boolean incoming) {
7113        enforceNotIsolatedCaller("getPersistedUriPermissions");
7114        Preconditions.checkNotNull(packageName, "packageName");
7115
7116        final int callingUid = Binder.getCallingUid();
7117        final IPackageManager pm = AppGlobals.getPackageManager();
7118        try {
7119            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7120            if (packageUid != callingUid) {
7121                throw new SecurityException(
7122                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7123            }
7124        } catch (RemoteException e) {
7125            throw new SecurityException("Failed to verify package name ownership");
7126        }
7127
7128        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7129        synchronized (this) {
7130            if (incoming) {
7131                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7132                        callingUid);
7133                if (perms == null) {
7134                    Slog.w(TAG, "No permission grants found for " + packageName);
7135                } else {
7136                    for (UriPermission perm : perms.values()) {
7137                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7138                            result.add(perm.buildPersistedPublicApiObject());
7139                        }
7140                    }
7141                }
7142            } else {
7143                final int size = mGrantedUriPermissions.size();
7144                for (int i = 0; i < size; i++) {
7145                    final ArrayMap<GrantUri, UriPermission> perms =
7146                            mGrantedUriPermissions.valueAt(i);
7147                    for (UriPermission perm : perms.values()) {
7148                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7149                            result.add(perm.buildPersistedPublicApiObject());
7150                        }
7151                    }
7152                }
7153            }
7154        }
7155        return new ParceledListSlice<android.content.UriPermission>(result);
7156    }
7157
7158    @Override
7159    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7160        synchronized (this) {
7161            ProcessRecord app =
7162                who != null ? getRecordForAppLocked(who) : null;
7163            if (app == null) return;
7164
7165            Message msg = Message.obtain();
7166            msg.what = WAIT_FOR_DEBUGGER_MSG;
7167            msg.obj = app;
7168            msg.arg1 = waiting ? 1 : 0;
7169            mHandler.sendMessage(msg);
7170        }
7171    }
7172
7173    @Override
7174    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7175        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7176        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7177        outInfo.availMem = Process.getFreeMemory();
7178        outInfo.totalMem = Process.getTotalMemory();
7179        outInfo.threshold = homeAppMem;
7180        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7181        outInfo.hiddenAppThreshold = cachedAppMem;
7182        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7183                ProcessList.SERVICE_ADJ);
7184        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7185                ProcessList.VISIBLE_APP_ADJ);
7186        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7187                ProcessList.FOREGROUND_APP_ADJ);
7188    }
7189
7190    // =========================================================
7191    // TASK MANAGEMENT
7192    // =========================================================
7193
7194    @Override
7195    public List<IAppTask> getAppTasks() {
7196        final PackageManager pm = mContext.getPackageManager();
7197        int callingUid = Binder.getCallingUid();
7198        long ident = Binder.clearCallingIdentity();
7199
7200        // Compose the list of packages for this id to test against
7201        HashSet<String> packages = new HashSet<String>();
7202        String[] uidPackages = pm.getPackagesForUid(callingUid);
7203        for (int i = 0; i < uidPackages.length; i++) {
7204            packages.add(uidPackages[i]);
7205        }
7206
7207        synchronized(this) {
7208            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7209            try {
7210                if (localLOGV) Slog.v(TAG, "getAppTasks");
7211
7212                final int N = mRecentTasks.size();
7213                for (int i = 0; i < N; i++) {
7214                    TaskRecord tr = mRecentTasks.get(i);
7215                    // Skip tasks that are not created by the caller
7216                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7217                        ActivityManager.RecentTaskInfo taskInfo =
7218                                createRecentTaskInfoFromTaskRecord(tr);
7219                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7220                        list.add(taskImpl);
7221                    }
7222                }
7223            } finally {
7224                Binder.restoreCallingIdentity(ident);
7225            }
7226            return list;
7227        }
7228    }
7229
7230    @Override
7231    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7232        final int callingUid = Binder.getCallingUid();
7233        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7234
7235        synchronized(this) {
7236            if (localLOGV) Slog.v(
7237                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7238
7239            final boolean allowed = checkCallingPermission(
7240                    android.Manifest.permission.GET_TASKS)
7241                    == PackageManager.PERMISSION_GRANTED;
7242            if (!allowed) {
7243                Slog.w(TAG, "getTasks: caller " + callingUid
7244                        + " does not hold GET_TASKS; limiting output");
7245            }
7246
7247            // TODO: Improve with MRU list from all ActivityStacks.
7248            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7249        }
7250
7251        return list;
7252    }
7253
7254    TaskRecord getMostRecentTask() {
7255        return mRecentTasks.get(0);
7256    }
7257
7258    /**
7259     * Creates a new RecentTaskInfo from a TaskRecord.
7260     */
7261    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7262        // Update the task description to reflect any changes in the task stack
7263        tr.updateTaskDescription();
7264
7265        // Compose the recent task info
7266        ActivityManager.RecentTaskInfo rti
7267                = new ActivityManager.RecentTaskInfo();
7268        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7269        rti.persistentId = tr.taskId;
7270        rti.baseIntent = new Intent(tr.getBaseIntent());
7271        rti.origActivity = tr.origActivity;
7272        rti.description = tr.lastDescription;
7273        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7274        rti.userId = tr.userId;
7275        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7276        rti.firstActiveTime = tr.firstActiveTime;
7277        rti.lastActiveTime = tr.lastActiveTime;
7278        return rti;
7279    }
7280
7281    @Override
7282    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7283            int flags, int userId) {
7284        final int callingUid = Binder.getCallingUid();
7285        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7286                false, true, "getRecentTasks", null);
7287
7288        synchronized (this) {
7289            final boolean allowed = checkCallingPermission(
7290                    android.Manifest.permission.GET_TASKS)
7291                    == PackageManager.PERMISSION_GRANTED;
7292            if (!allowed) {
7293                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7294                        + " does not hold GET_TASKS; limiting output");
7295            }
7296            final boolean detailed = checkCallingPermission(
7297                    android.Manifest.permission.GET_DETAILED_TASKS)
7298                    == PackageManager.PERMISSION_GRANTED;
7299
7300            IPackageManager pm = AppGlobals.getPackageManager();
7301
7302            final int N = mRecentTasks.size();
7303            ArrayList<ActivityManager.RecentTaskInfo> res
7304                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7305                            maxNum < N ? maxNum : N);
7306
7307            final Set<Integer> includedUsers;
7308            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7309                includedUsers = getProfileIdsLocked(userId);
7310            } else {
7311                includedUsers = new HashSet<Integer>();
7312            }
7313            includedUsers.add(Integer.valueOf(userId));
7314            for (int i=0; i<N && maxNum > 0; i++) {
7315                TaskRecord tr = mRecentTasks.get(i);
7316                // Only add calling user or related users recent tasks
7317                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7318
7319                // Return the entry if desired by the caller.  We always return
7320                // the first entry, because callers always expect this to be the
7321                // foreground app.  We may filter others if the caller has
7322                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7323                // we should exclude the entry.
7324
7325                if (i == 0
7326                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7327                        || (tr.intent == null)
7328                        || ((tr.intent.getFlags()
7329                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7330                    if (!allowed) {
7331                        // If the caller doesn't have the GET_TASKS permission, then only
7332                        // allow them to see a small subset of tasks -- their own and home.
7333                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7334                            continue;
7335                        }
7336                    }
7337                    if (tr.intent != null &&
7338                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7339                            != 0 && tr.getTopActivity() == null) {
7340                        // Don't include auto remove tasks that are finished or finishing.
7341                        continue;
7342                    }
7343
7344                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7345                    if (!detailed) {
7346                        rti.baseIntent.replaceExtras((Bundle)null);
7347                    }
7348
7349                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7350                        // Check whether this activity is currently available.
7351                        try {
7352                            if (rti.origActivity != null) {
7353                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7354                                        == null) {
7355                                    continue;
7356                                }
7357                            } else if (rti.baseIntent != null) {
7358                                if (pm.queryIntentActivities(rti.baseIntent,
7359                                        null, 0, userId) == null) {
7360                                    continue;
7361                                }
7362                            }
7363                        } catch (RemoteException e) {
7364                            // Will never happen.
7365                        }
7366                    }
7367
7368                    res.add(rti);
7369                    maxNum--;
7370                }
7371            }
7372            return res;
7373        }
7374    }
7375
7376    private TaskRecord recentTaskForIdLocked(int id) {
7377        final int N = mRecentTasks.size();
7378            for (int i=0; i<N; i++) {
7379                TaskRecord tr = mRecentTasks.get(i);
7380                if (tr.taskId == id) {
7381                    return tr;
7382                }
7383            }
7384            return null;
7385    }
7386
7387    @Override
7388    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7389        synchronized (this) {
7390            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7391                    "getTaskThumbnail()");
7392            TaskRecord tr = recentTaskForIdLocked(id);
7393            if (tr != null) {
7394                return tr.getTaskThumbnailLocked();
7395            }
7396        }
7397        return null;
7398    }
7399
7400    @Override
7401    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7402        synchronized (this) {
7403            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7404            if (r != null) {
7405                r.taskDescription = td;
7406                r.task.updateTaskDescription();
7407            }
7408        }
7409    }
7410
7411    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7412        if (!pr.killedByAm) {
7413            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7414            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7415                    pr.processName, pr.setAdj, reason);
7416            pr.killedByAm = true;
7417            Process.killProcessQuiet(pr.pid);
7418        }
7419    }
7420
7421    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7422        tr.disposeThumbnail();
7423        mRecentTasks.remove(tr);
7424        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7425        Intent baseIntent = new Intent(
7426                tr.intent != null ? tr.intent : tr.affinityIntent);
7427        ComponentName component = baseIntent.getComponent();
7428        if (component == null) {
7429            Slog.w(TAG, "Now component for base intent of task: " + tr);
7430            return;
7431        }
7432
7433        // Find any running services associated with this app.
7434        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7435
7436        if (killProcesses) {
7437            // Find any running processes associated with this app.
7438            final String pkg = component.getPackageName();
7439            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7440            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7441            for (int i=0; i<pmap.size(); i++) {
7442                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7443                for (int j=0; j<uids.size(); j++) {
7444                    ProcessRecord proc = uids.valueAt(j);
7445                    if (proc.userId != tr.userId) {
7446                        continue;
7447                    }
7448                    if (!proc.pkgList.containsKey(pkg)) {
7449                        continue;
7450                    }
7451                    procs.add(proc);
7452                }
7453            }
7454
7455            // Kill the running processes.
7456            for (int i=0; i<procs.size(); i++) {
7457                ProcessRecord pr = procs.get(i);
7458                if (pr == mHomeProcess) {
7459                    // Don't kill the home process along with tasks from the same package.
7460                    continue;
7461                }
7462                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7463                    killUnneededProcessLocked(pr, "remove task");
7464                } else {
7465                    pr.waitingToKill = "remove task";
7466                }
7467            }
7468        }
7469    }
7470
7471    /**
7472     * Removes the task with the specified task id.
7473     *
7474     * @param taskId Identifier of the task to be removed.
7475     * @param flags Additional operational flags.  May be 0 or
7476     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7477     * @return Returns true if the given task was found and removed.
7478     */
7479    private boolean removeTaskByIdLocked(int taskId, int flags) {
7480        TaskRecord tr = recentTaskForIdLocked(taskId);
7481        if (tr != null) {
7482            tr.removeTaskActivitiesLocked();
7483            cleanUpRemovedTaskLocked(tr, flags);
7484            if (tr.isPersistable) {
7485                notifyTaskPersisterLocked(tr, true);
7486            }
7487            return true;
7488        }
7489        return false;
7490    }
7491
7492    @Override
7493    public boolean removeTask(int taskId, int flags) {
7494        synchronized (this) {
7495            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7496                    "removeTask()");
7497            long ident = Binder.clearCallingIdentity();
7498            try {
7499                return removeTaskByIdLocked(taskId, flags);
7500            } finally {
7501                Binder.restoreCallingIdentity(ident);
7502            }
7503        }
7504    }
7505
7506    /**
7507     * TODO: Add mController hook
7508     */
7509    @Override
7510    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7511        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7512                "moveTaskToFront()");
7513
7514        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7515        synchronized(this) {
7516            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7517                    Binder.getCallingUid(), "Task to front")) {
7518                ActivityOptions.abort(options);
7519                return;
7520            }
7521            final long origId = Binder.clearCallingIdentity();
7522            try {
7523                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7524                if (task == null) {
7525                    return;
7526                }
7527                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7528                    mStackSupervisor.showLockTaskToast();
7529                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7530                    return;
7531                }
7532                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7533                if (prev != null && prev.isRecentsActivity()) {
7534                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7535                }
7536                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7537            } finally {
7538                Binder.restoreCallingIdentity(origId);
7539            }
7540            ActivityOptions.abort(options);
7541        }
7542    }
7543
7544    @Override
7545    public void moveTaskToBack(int taskId) {
7546        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7547                "moveTaskToBack()");
7548
7549        synchronized(this) {
7550            TaskRecord tr = recentTaskForIdLocked(taskId);
7551            if (tr != null) {
7552                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7553                ActivityStack stack = tr.stack;
7554                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7555                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7556                            Binder.getCallingUid(), "Task to back")) {
7557                        return;
7558                    }
7559                }
7560                final long origId = Binder.clearCallingIdentity();
7561                try {
7562                    stack.moveTaskToBackLocked(taskId, null);
7563                } finally {
7564                    Binder.restoreCallingIdentity(origId);
7565                }
7566            }
7567        }
7568    }
7569
7570    /**
7571     * Moves an activity, and all of the other activities within the same task, to the bottom
7572     * of the history stack.  The activity's order within the task is unchanged.
7573     *
7574     * @param token A reference to the activity we wish to move
7575     * @param nonRoot If false then this only works if the activity is the root
7576     *                of a task; if true it will work for any activity in a task.
7577     * @return Returns true if the move completed, false if not.
7578     */
7579    @Override
7580    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7581        enforceNotIsolatedCaller("moveActivityTaskToBack");
7582        synchronized(this) {
7583            final long origId = Binder.clearCallingIdentity();
7584            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7585            if (taskId >= 0) {
7586                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7587            }
7588            Binder.restoreCallingIdentity(origId);
7589        }
7590        return false;
7591    }
7592
7593    @Override
7594    public void moveTaskBackwards(int task) {
7595        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7596                "moveTaskBackwards()");
7597
7598        synchronized(this) {
7599            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7600                    Binder.getCallingUid(), "Task backwards")) {
7601                return;
7602            }
7603            final long origId = Binder.clearCallingIdentity();
7604            moveTaskBackwardsLocked(task);
7605            Binder.restoreCallingIdentity(origId);
7606        }
7607    }
7608
7609    private final void moveTaskBackwardsLocked(int task) {
7610        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7611    }
7612
7613    @Override
7614    public IBinder getHomeActivityToken() throws RemoteException {
7615        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7616                "getHomeActivityToken()");
7617        synchronized (this) {
7618            return mStackSupervisor.getHomeActivityToken();
7619        }
7620    }
7621
7622    @Override
7623    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7624            IActivityContainerCallback callback) throws RemoteException {
7625        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7626                "createActivityContainer()");
7627        synchronized (this) {
7628            if (parentActivityToken == null) {
7629                throw new IllegalArgumentException("parent token must not be null");
7630            }
7631            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7632            if (r == null) {
7633                return null;
7634            }
7635            if (callback == null) {
7636                throw new IllegalArgumentException("callback must not be null");
7637            }
7638            return mStackSupervisor.createActivityContainer(r, callback);
7639        }
7640    }
7641
7642    @Override
7643    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7644        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7645                "deleteActivityContainer()");
7646        synchronized (this) {
7647            mStackSupervisor.deleteActivityContainer(container);
7648        }
7649    }
7650
7651    @Override
7652    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7653            throws RemoteException {
7654        synchronized (this) {
7655            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7656            if (stack != null) {
7657                return stack.mActivityContainer;
7658            }
7659            return null;
7660        }
7661    }
7662
7663    @Override
7664    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7665        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7666                "moveTaskToStack()");
7667        if (stackId == HOME_STACK_ID) {
7668            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7669                    new RuntimeException("here").fillInStackTrace());
7670        }
7671        synchronized (this) {
7672            long ident = Binder.clearCallingIdentity();
7673            try {
7674                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7675                        + stackId + " toTop=" + toTop);
7676                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7677            } finally {
7678                Binder.restoreCallingIdentity(ident);
7679            }
7680        }
7681    }
7682
7683    @Override
7684    public void resizeStack(int stackBoxId, Rect bounds) {
7685        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7686                "resizeStackBox()");
7687        long ident = Binder.clearCallingIdentity();
7688        try {
7689            mWindowManager.resizeStack(stackBoxId, bounds);
7690        } finally {
7691            Binder.restoreCallingIdentity(ident);
7692        }
7693    }
7694
7695    @Override
7696    public List<StackInfo> getAllStackInfos() {
7697        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7698                "getAllStackInfos()");
7699        long ident = Binder.clearCallingIdentity();
7700        try {
7701            synchronized (this) {
7702                return mStackSupervisor.getAllStackInfosLocked();
7703            }
7704        } finally {
7705            Binder.restoreCallingIdentity(ident);
7706        }
7707    }
7708
7709    @Override
7710    public StackInfo getStackInfo(int stackId) {
7711        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7712                "getStackInfo()");
7713        long ident = Binder.clearCallingIdentity();
7714        try {
7715            synchronized (this) {
7716                return mStackSupervisor.getStackInfoLocked(stackId);
7717            }
7718        } finally {
7719            Binder.restoreCallingIdentity(ident);
7720        }
7721    }
7722
7723    @Override
7724    public boolean isInHomeStack(int taskId) {
7725        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7726                "getStackInfo()");
7727        long ident = Binder.clearCallingIdentity();
7728        try {
7729            synchronized (this) {
7730                TaskRecord tr = recentTaskForIdLocked(taskId);
7731                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7732            }
7733        } finally {
7734            Binder.restoreCallingIdentity(ident);
7735        }
7736    }
7737
7738    @Override
7739    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7740        synchronized(this) {
7741            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7742        }
7743    }
7744
7745    private boolean isLockTaskAuthorized(String pkg) {
7746        final DevicePolicyManager dpm = (DevicePolicyManager)
7747                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7748        try {
7749            int uid = mContext.getPackageManager().getPackageUid(pkg,
7750                    Binder.getCallingUserHandle().getIdentifier());
7751            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7752        } catch (NameNotFoundException e) {
7753            return false;
7754        }
7755    }
7756
7757    void startLockTaskMode(TaskRecord task) {
7758        final String pkg;
7759        synchronized (this) {
7760            pkg = task.intent.getComponent().getPackageName();
7761        }
7762        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7763        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7764            final TaskRecord taskRecord = task;
7765            mHandler.post(new Runnable() {
7766                @Override
7767                public void run() {
7768                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7769                }
7770            });
7771            return;
7772        }
7773        long ident = Binder.clearCallingIdentity();
7774        try {
7775            synchronized (this) {
7776                // Since we lost lock on task, make sure it is still there.
7777                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7778                if (task != null) {
7779                    if (!isSystemInitiated
7780                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7781                        throw new IllegalArgumentException("Invalid task, not in foreground");
7782                    }
7783                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7784                }
7785            }
7786        } finally {
7787            Binder.restoreCallingIdentity(ident);
7788        }
7789    }
7790
7791    @Override
7792    public void startLockTaskMode(int taskId) {
7793        final TaskRecord task;
7794        long ident = Binder.clearCallingIdentity();
7795        try {
7796            synchronized (this) {
7797                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7798            }
7799        } finally {
7800            Binder.restoreCallingIdentity(ident);
7801        }
7802        if (task != null) {
7803            startLockTaskMode(task);
7804        }
7805    }
7806
7807    @Override
7808    public void startLockTaskMode(IBinder token) {
7809        final TaskRecord task;
7810        long ident = Binder.clearCallingIdentity();
7811        try {
7812            synchronized (this) {
7813                final ActivityRecord r = ActivityRecord.forToken(token);
7814                if (r == null) {
7815                    return;
7816                }
7817                task = r.task;
7818            }
7819        } finally {
7820            Binder.restoreCallingIdentity(ident);
7821        }
7822        if (task != null) {
7823            startLockTaskMode(task);
7824        }
7825    }
7826
7827    @Override
7828    public void startLockTaskModeOnCurrent() throws RemoteException {
7829        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7830        ActivityRecord r = null;
7831        synchronized (this) {
7832            r = mStackSupervisor.topRunningActivityLocked();
7833        }
7834        startLockTaskMode(r.task);
7835    }
7836
7837    @Override
7838    public void stopLockTaskMode() {
7839        // Verify that the user matches the package of the intent for the TaskRecord
7840        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7841        // and stopLockTaskMode.
7842        final int callingUid = Binder.getCallingUid();
7843        if (callingUid != Process.SYSTEM_UID) {
7844            try {
7845                String pkg =
7846                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7847                int uid = mContext.getPackageManager().getPackageUid(pkg,
7848                        Binder.getCallingUserHandle().getIdentifier());
7849                if (uid != callingUid) {
7850                    throw new SecurityException("Invalid uid, expected " + uid);
7851                }
7852            } catch (NameNotFoundException e) {
7853                Log.d(TAG, "stopLockTaskMode " + e);
7854                return;
7855            }
7856        }
7857        long ident = Binder.clearCallingIdentity();
7858        try {
7859            Log.d(TAG, "stopLockTaskMode");
7860            // Stop lock task
7861            synchronized (this) {
7862                mStackSupervisor.setLockTaskModeLocked(null, false);
7863            }
7864        } finally {
7865            Binder.restoreCallingIdentity(ident);
7866        }
7867    }
7868
7869    @Override
7870    public void stopLockTaskModeOnCurrent() throws RemoteException {
7871        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7872        long ident = Binder.clearCallingIdentity();
7873        try {
7874            stopLockTaskMode();
7875        } finally {
7876            Binder.restoreCallingIdentity(ident);
7877        }
7878    }
7879
7880    @Override
7881    public boolean isInLockTaskMode() {
7882        synchronized (this) {
7883            return mStackSupervisor.isInLockTaskMode();
7884        }
7885    }
7886
7887    // =========================================================
7888    // CONTENT PROVIDERS
7889    // =========================================================
7890
7891    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7892        List<ProviderInfo> providers = null;
7893        try {
7894            providers = AppGlobals.getPackageManager().
7895                queryContentProviders(app.processName, app.uid,
7896                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7897        } catch (RemoteException ex) {
7898        }
7899        if (DEBUG_MU)
7900            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7901        int userId = app.userId;
7902        if (providers != null) {
7903            int N = providers.size();
7904            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7905            for (int i=0; i<N; i++) {
7906                ProviderInfo cpi =
7907                    (ProviderInfo)providers.get(i);
7908                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7909                        cpi.name, cpi.flags);
7910                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7911                    // This is a singleton provider, but a user besides the
7912                    // default user is asking to initialize a process it runs
7913                    // in...  well, no, it doesn't actually run in this process,
7914                    // it runs in the process of the default user.  Get rid of it.
7915                    providers.remove(i);
7916                    N--;
7917                    i--;
7918                    continue;
7919                }
7920
7921                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7922                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7923                if (cpr == null) {
7924                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7925                    mProviderMap.putProviderByClass(comp, cpr);
7926                }
7927                if (DEBUG_MU)
7928                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7929                app.pubProviders.put(cpi.name, cpr);
7930                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7931                    // Don't add this if it is a platform component that is marked
7932                    // to run in multiple processes, because this is actually
7933                    // part of the framework so doesn't make sense to track as a
7934                    // separate apk in the process.
7935                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7936                            mProcessStats);
7937                }
7938                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7939            }
7940        }
7941        return providers;
7942    }
7943
7944    /**
7945     * Check if {@link ProcessRecord} has a possible chance at accessing the
7946     * given {@link ProviderInfo}. Final permission checking is always done
7947     * in {@link ContentProvider}.
7948     */
7949    private final String checkContentProviderPermissionLocked(
7950            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7951        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7952        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7953        boolean checkedGrants = false;
7954        if (checkUser) {
7955            // Looking for cross-user grants before enforcing the typical cross-users permissions
7956            if (UserHandle.getUserId(callingUid) != userId) {
7957                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7958                    return null;
7959                }
7960                checkedGrants = true;
7961            }
7962            userId = handleIncomingUser(callingPid, callingUid, userId,
7963                    false, false, "checkContentProviderPermissionLocked " + cpi.authority, null);
7964        }
7965        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7966                cpi.applicationInfo.uid, cpi.exported)
7967                == PackageManager.PERMISSION_GRANTED) {
7968            return null;
7969        }
7970        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7971                cpi.applicationInfo.uid, cpi.exported)
7972                == PackageManager.PERMISSION_GRANTED) {
7973            return null;
7974        }
7975
7976        PathPermission[] pps = cpi.pathPermissions;
7977        if (pps != null) {
7978            int i = pps.length;
7979            while (i > 0) {
7980                i--;
7981                PathPermission pp = pps[i];
7982                String pprperm = pp.getReadPermission();
7983                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
7984                        cpi.applicationInfo.uid, cpi.exported)
7985                        == PackageManager.PERMISSION_GRANTED) {
7986                    return null;
7987                }
7988                String ppwperm = pp.getWritePermission();
7989                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
7990                        cpi.applicationInfo.uid, cpi.exported)
7991                        == PackageManager.PERMISSION_GRANTED) {
7992                    return null;
7993                }
7994            }
7995        }
7996        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7997            return null;
7998        }
7999
8000        String msg;
8001        if (!cpi.exported) {
8002            msg = "Permission Denial: opening provider " + cpi.name
8003                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8004                    + ", uid=" + callingUid + ") that is not exported from uid "
8005                    + cpi.applicationInfo.uid;
8006        } else {
8007            msg = "Permission Denial: opening provider " + cpi.name
8008                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8009                    + ", uid=" + callingUid + ") requires "
8010                    + cpi.readPermission + " or " + cpi.writePermission;
8011        }
8012        Slog.w(TAG, msg);
8013        return msg;
8014    }
8015
8016    /**
8017     * Returns if the ContentProvider has granted a uri to callingUid
8018     */
8019    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8020        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8021        if (perms != null) {
8022            for (GrantUri grantUri : perms.keySet()) {
8023                if (grantUri.sourceUserId == userId || !checkUser) {
8024                    if (matchesProvider(grantUri.uri, cpi)) {
8025                        return true;
8026                    }
8027                }
8028            }
8029        }
8030        return false;
8031    }
8032
8033    /**
8034     * Returns true if the uri authority is one of the authorities specified in the provider.
8035     */
8036    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8037        String uriAuth = uri.getAuthority();
8038        String cpiAuth = cpi.authority;
8039        if (cpiAuth.indexOf(';') == -1) {
8040            return cpiAuth.equals(uriAuth);
8041        }
8042        String[] cpiAuths = cpiAuth.split(";");
8043        int length = cpiAuths.length;
8044        for (int i = 0; i < length; i++) {
8045            if (cpiAuths[i].equals(uriAuth)) return true;
8046        }
8047        return false;
8048    }
8049
8050    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8051            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8052        if (r != null) {
8053            for (int i=0; i<r.conProviders.size(); i++) {
8054                ContentProviderConnection conn = r.conProviders.get(i);
8055                if (conn.provider == cpr) {
8056                    if (DEBUG_PROVIDER) Slog.v(TAG,
8057                            "Adding provider requested by "
8058                            + r.processName + " from process "
8059                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8060                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8061                    if (stable) {
8062                        conn.stableCount++;
8063                        conn.numStableIncs++;
8064                    } else {
8065                        conn.unstableCount++;
8066                        conn.numUnstableIncs++;
8067                    }
8068                    return conn;
8069                }
8070            }
8071            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8072            if (stable) {
8073                conn.stableCount = 1;
8074                conn.numStableIncs = 1;
8075            } else {
8076                conn.unstableCount = 1;
8077                conn.numUnstableIncs = 1;
8078            }
8079            cpr.connections.add(conn);
8080            r.conProviders.add(conn);
8081            return conn;
8082        }
8083        cpr.addExternalProcessHandleLocked(externalProcessToken);
8084        return null;
8085    }
8086
8087    boolean decProviderCountLocked(ContentProviderConnection conn,
8088            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8089        if (conn != null) {
8090            cpr = conn.provider;
8091            if (DEBUG_PROVIDER) Slog.v(TAG,
8092                    "Removing provider requested by "
8093                    + conn.client.processName + " from process "
8094                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8095                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8096            if (stable) {
8097                conn.stableCount--;
8098            } else {
8099                conn.unstableCount--;
8100            }
8101            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8102                cpr.connections.remove(conn);
8103                conn.client.conProviders.remove(conn);
8104                return true;
8105            }
8106            return false;
8107        }
8108        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8109        return false;
8110    }
8111
8112    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8113            String name, IBinder token, boolean stable, int userId) {
8114        ContentProviderRecord cpr;
8115        ContentProviderConnection conn = null;
8116        ProviderInfo cpi = null;
8117
8118        synchronized(this) {
8119            ProcessRecord r = null;
8120            if (caller != null) {
8121                r = getRecordForAppLocked(caller);
8122                if (r == null) {
8123                    throw new SecurityException(
8124                            "Unable to find app for caller " + caller
8125                          + " (pid=" + Binder.getCallingPid()
8126                          + ") when getting content provider " + name);
8127                }
8128            }
8129
8130            boolean checkCrossUser = true;
8131
8132            // First check if this content provider has been published...
8133            cpr = mProviderMap.getProviderByName(name, userId);
8134            // If that didn't work, check if it exists for user 0 and then
8135            // verify that it's a singleton provider before using it.
8136            if (cpr == null && userId != UserHandle.USER_OWNER) {
8137                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8138                if (cpr != null) {
8139                    cpi = cpr.info;
8140                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8141                            cpi.name, cpi.flags)
8142                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8143                        userId = UserHandle.USER_OWNER;
8144                        checkCrossUser = false;
8145                    } else {
8146                        cpr = null;
8147                        cpi = null;
8148                    }
8149                }
8150            }
8151
8152            boolean providerRunning = cpr != null;
8153            if (providerRunning) {
8154                cpi = cpr.info;
8155                String msg;
8156                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8157                        != null) {
8158                    throw new SecurityException(msg);
8159                }
8160
8161                if (r != null && cpr.canRunHere(r)) {
8162                    // This provider has been published or is in the process
8163                    // of being published...  but it is also allowed to run
8164                    // in the caller's process, so don't make a connection
8165                    // and just let the caller instantiate its own instance.
8166                    ContentProviderHolder holder = cpr.newHolder(null);
8167                    // don't give caller the provider object, it needs
8168                    // to make its own.
8169                    holder.provider = null;
8170                    return holder;
8171                }
8172
8173                final long origId = Binder.clearCallingIdentity();
8174
8175                // In this case the provider instance already exists, so we can
8176                // return it right away.
8177                conn = incProviderCountLocked(r, cpr, token, stable);
8178                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8179                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8180                        // If this is a perceptible app accessing the provider,
8181                        // make sure to count it as being accessed and thus
8182                        // back up on the LRU list.  This is good because
8183                        // content providers are often expensive to start.
8184                        updateLruProcessLocked(cpr.proc, false, null);
8185                    }
8186                }
8187
8188                if (cpr.proc != null) {
8189                    if (false) {
8190                        if (cpr.name.flattenToShortString().equals(
8191                                "com.android.providers.calendar/.CalendarProvider2")) {
8192                            Slog.v(TAG, "****************** KILLING "
8193                                + cpr.name.flattenToShortString());
8194                            Process.killProcess(cpr.proc.pid);
8195                        }
8196                    }
8197                    boolean success = updateOomAdjLocked(cpr.proc);
8198                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8199                    // NOTE: there is still a race here where a signal could be
8200                    // pending on the process even though we managed to update its
8201                    // adj level.  Not sure what to do about this, but at least
8202                    // the race is now smaller.
8203                    if (!success) {
8204                        // Uh oh...  it looks like the provider's process
8205                        // has been killed on us.  We need to wait for a new
8206                        // process to be started, and make sure its death
8207                        // doesn't kill our process.
8208                        Slog.i(TAG,
8209                                "Existing provider " + cpr.name.flattenToShortString()
8210                                + " is crashing; detaching " + r);
8211                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8212                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8213                        if (!lastRef) {
8214                            // This wasn't the last ref our process had on
8215                            // the provider...  we have now been killed, bail.
8216                            return null;
8217                        }
8218                        providerRunning = false;
8219                        conn = null;
8220                    }
8221                }
8222
8223                Binder.restoreCallingIdentity(origId);
8224            }
8225
8226            boolean singleton;
8227            if (!providerRunning) {
8228                try {
8229                    cpi = AppGlobals.getPackageManager().
8230                        resolveContentProvider(name,
8231                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8232                } catch (RemoteException ex) {
8233                }
8234                if (cpi == null) {
8235                    return null;
8236                }
8237                // If the provider is a singleton AND
8238                // (it's a call within the same user || the provider is a
8239                // privileged app)
8240                // Then allow connecting to the singleton provider
8241                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8242                        cpi.name, cpi.flags)
8243                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8244                if (singleton) {
8245                    userId = UserHandle.USER_OWNER;
8246                }
8247                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8248
8249                String msg;
8250                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8251                        != null) {
8252                    throw new SecurityException(msg);
8253                }
8254
8255                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8256                        && !cpi.processName.equals("system")) {
8257                    // If this content provider does not run in the system
8258                    // process, and the system is not yet ready to run other
8259                    // processes, then fail fast instead of hanging.
8260                    throw new IllegalArgumentException(
8261                            "Attempt to launch content provider before system ready");
8262                }
8263
8264                // Make sure that the user who owns this provider is started.  If not,
8265                // we don't want to allow it to run.
8266                if (mStartedUsers.get(userId) == null) {
8267                    Slog.w(TAG, "Unable to launch app "
8268                            + cpi.applicationInfo.packageName + "/"
8269                            + cpi.applicationInfo.uid + " for provider "
8270                            + name + ": user " + userId + " is stopped");
8271                    return null;
8272                }
8273
8274                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8275                cpr = mProviderMap.getProviderByClass(comp, userId);
8276                final boolean firstClass = cpr == null;
8277                if (firstClass) {
8278                    try {
8279                        ApplicationInfo ai =
8280                            AppGlobals.getPackageManager().
8281                                getApplicationInfo(
8282                                        cpi.applicationInfo.packageName,
8283                                        STOCK_PM_FLAGS, userId);
8284                        if (ai == null) {
8285                            Slog.w(TAG, "No package info for content provider "
8286                                    + cpi.name);
8287                            return null;
8288                        }
8289                        ai = getAppInfoForUser(ai, userId);
8290                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8291                    } catch (RemoteException ex) {
8292                        // pm is in same process, this will never happen.
8293                    }
8294                }
8295
8296                if (r != null && cpr.canRunHere(r)) {
8297                    // If this is a multiprocess provider, then just return its
8298                    // info and allow the caller to instantiate it.  Only do
8299                    // this if the provider is the same user as the caller's
8300                    // process, or can run as root (so can be in any process).
8301                    return cpr.newHolder(null);
8302                }
8303
8304                if (DEBUG_PROVIDER) {
8305                    RuntimeException e = new RuntimeException("here");
8306                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8307                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8308                }
8309
8310                // This is single process, and our app is now connecting to it.
8311                // See if we are already in the process of launching this
8312                // provider.
8313                final int N = mLaunchingProviders.size();
8314                int i;
8315                for (i=0; i<N; i++) {
8316                    if (mLaunchingProviders.get(i) == cpr) {
8317                        break;
8318                    }
8319                }
8320
8321                // If the provider is not already being launched, then get it
8322                // started.
8323                if (i >= N) {
8324                    final long origId = Binder.clearCallingIdentity();
8325
8326                    try {
8327                        // Content provider is now in use, its package can't be stopped.
8328                        try {
8329                            AppGlobals.getPackageManager().setPackageStoppedState(
8330                                    cpr.appInfo.packageName, false, userId);
8331                        } catch (RemoteException e) {
8332                        } catch (IllegalArgumentException e) {
8333                            Slog.w(TAG, "Failed trying to unstop package "
8334                                    + cpr.appInfo.packageName + ": " + e);
8335                        }
8336
8337                        // Use existing process if already started
8338                        ProcessRecord proc = getProcessRecordLocked(
8339                                cpi.processName, cpr.appInfo.uid, false);
8340                        if (proc != null && proc.thread != null) {
8341                            if (DEBUG_PROVIDER) {
8342                                Slog.d(TAG, "Installing in existing process " + proc);
8343                            }
8344                            proc.pubProviders.put(cpi.name, cpr);
8345                            try {
8346                                proc.thread.scheduleInstallProvider(cpi);
8347                            } catch (RemoteException e) {
8348                            }
8349                        } else {
8350                            proc = startProcessLocked(cpi.processName,
8351                                    cpr.appInfo, false, 0, "content provider",
8352                                    new ComponentName(cpi.applicationInfo.packageName,
8353                                            cpi.name), false, false, false);
8354                            if (proc == null) {
8355                                Slog.w(TAG, "Unable to launch app "
8356                                        + cpi.applicationInfo.packageName + "/"
8357                                        + cpi.applicationInfo.uid + " for provider "
8358                                        + name + ": process is bad");
8359                                return null;
8360                            }
8361                        }
8362                        cpr.launchingApp = proc;
8363                        mLaunchingProviders.add(cpr);
8364                    } finally {
8365                        Binder.restoreCallingIdentity(origId);
8366                    }
8367                }
8368
8369                // Make sure the provider is published (the same provider class
8370                // may be published under multiple names).
8371                if (firstClass) {
8372                    mProviderMap.putProviderByClass(comp, cpr);
8373                }
8374
8375                mProviderMap.putProviderByName(name, cpr);
8376                conn = incProviderCountLocked(r, cpr, token, stable);
8377                if (conn != null) {
8378                    conn.waiting = true;
8379                }
8380            }
8381        }
8382
8383        // Wait for the provider to be published...
8384        synchronized (cpr) {
8385            while (cpr.provider == null) {
8386                if (cpr.launchingApp == null) {
8387                    Slog.w(TAG, "Unable to launch app "
8388                            + cpi.applicationInfo.packageName + "/"
8389                            + cpi.applicationInfo.uid + " for provider "
8390                            + name + ": launching app became null");
8391                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8392                            UserHandle.getUserId(cpi.applicationInfo.uid),
8393                            cpi.applicationInfo.packageName,
8394                            cpi.applicationInfo.uid, name);
8395                    return null;
8396                }
8397                try {
8398                    if (DEBUG_MU) {
8399                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8400                                + cpr.launchingApp);
8401                    }
8402                    if (conn != null) {
8403                        conn.waiting = true;
8404                    }
8405                    cpr.wait();
8406                } catch (InterruptedException ex) {
8407                } finally {
8408                    if (conn != null) {
8409                        conn.waiting = false;
8410                    }
8411                }
8412            }
8413        }
8414        return cpr != null ? cpr.newHolder(conn) : null;
8415    }
8416
8417    @Override
8418    public final ContentProviderHolder getContentProvider(
8419            IApplicationThread caller, String name, int userId, boolean stable) {
8420        enforceNotIsolatedCaller("getContentProvider");
8421        if (caller == null) {
8422            String msg = "null IApplicationThread when getting content provider "
8423                    + name;
8424            Slog.w(TAG, msg);
8425            throw new SecurityException(msg);
8426        }
8427        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8428        // with cross-user grant.
8429        return getContentProviderImpl(caller, name, null, stable, userId);
8430    }
8431
8432    public ContentProviderHolder getContentProviderExternal(
8433            String name, int userId, IBinder token) {
8434        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8435            "Do not have permission in call getContentProviderExternal()");
8436        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8437                false, true, "getContentProvider", null);
8438        return getContentProviderExternalUnchecked(name, token, userId);
8439    }
8440
8441    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8442            IBinder token, int userId) {
8443        return getContentProviderImpl(null, name, token, true, userId);
8444    }
8445
8446    /**
8447     * Drop a content provider from a ProcessRecord's bookkeeping
8448     */
8449    public void removeContentProvider(IBinder connection, boolean stable) {
8450        enforceNotIsolatedCaller("removeContentProvider");
8451        long ident = Binder.clearCallingIdentity();
8452        try {
8453            synchronized (this) {
8454                ContentProviderConnection conn;
8455                try {
8456                    conn = (ContentProviderConnection)connection;
8457                } catch (ClassCastException e) {
8458                    String msg ="removeContentProvider: " + connection
8459                            + " not a ContentProviderConnection";
8460                    Slog.w(TAG, msg);
8461                    throw new IllegalArgumentException(msg);
8462                }
8463                if (conn == null) {
8464                    throw new NullPointerException("connection is null");
8465                }
8466                if (decProviderCountLocked(conn, null, null, stable)) {
8467                    updateOomAdjLocked();
8468                }
8469            }
8470        } finally {
8471            Binder.restoreCallingIdentity(ident);
8472        }
8473    }
8474
8475    public void removeContentProviderExternal(String name, IBinder token) {
8476        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8477            "Do not have permission in call removeContentProviderExternal()");
8478        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8479    }
8480
8481    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8482        synchronized (this) {
8483            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8484            if(cpr == null) {
8485                //remove from mProvidersByClass
8486                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8487                return;
8488            }
8489
8490            //update content provider record entry info
8491            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8492            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8493            if (localCpr.hasExternalProcessHandles()) {
8494                if (localCpr.removeExternalProcessHandleLocked(token)) {
8495                    updateOomAdjLocked();
8496                } else {
8497                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8498                            + " with no external reference for token: "
8499                            + token + ".");
8500                }
8501            } else {
8502                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8503                        + " with no external references.");
8504            }
8505        }
8506    }
8507
8508    public final void publishContentProviders(IApplicationThread caller,
8509            List<ContentProviderHolder> providers) {
8510        if (providers == null) {
8511            return;
8512        }
8513
8514        enforceNotIsolatedCaller("publishContentProviders");
8515        synchronized (this) {
8516            final ProcessRecord r = getRecordForAppLocked(caller);
8517            if (DEBUG_MU)
8518                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8519            if (r == null) {
8520                throw new SecurityException(
8521                        "Unable to find app for caller " + caller
8522                      + " (pid=" + Binder.getCallingPid()
8523                      + ") when publishing content providers");
8524            }
8525
8526            final long origId = Binder.clearCallingIdentity();
8527
8528            final int N = providers.size();
8529            for (int i=0; i<N; i++) {
8530                ContentProviderHolder src = providers.get(i);
8531                if (src == null || src.info == null || src.provider == null) {
8532                    continue;
8533                }
8534                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8535                if (DEBUG_MU)
8536                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8537                if (dst != null) {
8538                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8539                    mProviderMap.putProviderByClass(comp, dst);
8540                    String names[] = dst.info.authority.split(";");
8541                    for (int j = 0; j < names.length; j++) {
8542                        mProviderMap.putProviderByName(names[j], dst);
8543                    }
8544
8545                    int NL = mLaunchingProviders.size();
8546                    int j;
8547                    for (j=0; j<NL; j++) {
8548                        if (mLaunchingProviders.get(j) == dst) {
8549                            mLaunchingProviders.remove(j);
8550                            j--;
8551                            NL--;
8552                        }
8553                    }
8554                    synchronized (dst) {
8555                        dst.provider = src.provider;
8556                        dst.proc = r;
8557                        dst.notifyAll();
8558                    }
8559                    updateOomAdjLocked(r);
8560                }
8561            }
8562
8563            Binder.restoreCallingIdentity(origId);
8564        }
8565    }
8566
8567    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8568        ContentProviderConnection conn;
8569        try {
8570            conn = (ContentProviderConnection)connection;
8571        } catch (ClassCastException e) {
8572            String msg ="refContentProvider: " + connection
8573                    + " not a ContentProviderConnection";
8574            Slog.w(TAG, msg);
8575            throw new IllegalArgumentException(msg);
8576        }
8577        if (conn == null) {
8578            throw new NullPointerException("connection is null");
8579        }
8580
8581        synchronized (this) {
8582            if (stable > 0) {
8583                conn.numStableIncs += stable;
8584            }
8585            stable = conn.stableCount + stable;
8586            if (stable < 0) {
8587                throw new IllegalStateException("stableCount < 0: " + stable);
8588            }
8589
8590            if (unstable > 0) {
8591                conn.numUnstableIncs += unstable;
8592            }
8593            unstable = conn.unstableCount + unstable;
8594            if (unstable < 0) {
8595                throw new IllegalStateException("unstableCount < 0: " + unstable);
8596            }
8597
8598            if ((stable+unstable) <= 0) {
8599                throw new IllegalStateException("ref counts can't go to zero here: stable="
8600                        + stable + " unstable=" + unstable);
8601            }
8602            conn.stableCount = stable;
8603            conn.unstableCount = unstable;
8604            return !conn.dead;
8605        }
8606    }
8607
8608    public void unstableProviderDied(IBinder connection) {
8609        ContentProviderConnection conn;
8610        try {
8611            conn = (ContentProviderConnection)connection;
8612        } catch (ClassCastException e) {
8613            String msg ="refContentProvider: " + connection
8614                    + " not a ContentProviderConnection";
8615            Slog.w(TAG, msg);
8616            throw new IllegalArgumentException(msg);
8617        }
8618        if (conn == null) {
8619            throw new NullPointerException("connection is null");
8620        }
8621
8622        // Safely retrieve the content provider associated with the connection.
8623        IContentProvider provider;
8624        synchronized (this) {
8625            provider = conn.provider.provider;
8626        }
8627
8628        if (provider == null) {
8629            // Um, yeah, we're way ahead of you.
8630            return;
8631        }
8632
8633        // Make sure the caller is being honest with us.
8634        if (provider.asBinder().pingBinder()) {
8635            // Er, no, still looks good to us.
8636            synchronized (this) {
8637                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8638                        + " says " + conn + " died, but we don't agree");
8639                return;
8640            }
8641        }
8642
8643        // Well look at that!  It's dead!
8644        synchronized (this) {
8645            if (conn.provider.provider != provider) {
8646                // But something changed...  good enough.
8647                return;
8648            }
8649
8650            ProcessRecord proc = conn.provider.proc;
8651            if (proc == null || proc.thread == null) {
8652                // Seems like the process is already cleaned up.
8653                return;
8654            }
8655
8656            // As far as we're concerned, this is just like receiving a
8657            // death notification...  just a bit prematurely.
8658            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8659                    + ") early provider death");
8660            final long ident = Binder.clearCallingIdentity();
8661            try {
8662                appDiedLocked(proc, proc.pid, proc.thread);
8663            } finally {
8664                Binder.restoreCallingIdentity(ident);
8665            }
8666        }
8667    }
8668
8669    @Override
8670    public void appNotRespondingViaProvider(IBinder connection) {
8671        enforceCallingPermission(
8672                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8673
8674        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8675        if (conn == null) {
8676            Slog.w(TAG, "ContentProviderConnection is null");
8677            return;
8678        }
8679
8680        final ProcessRecord host = conn.provider.proc;
8681        if (host == null) {
8682            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8683            return;
8684        }
8685
8686        final long token = Binder.clearCallingIdentity();
8687        try {
8688            appNotResponding(host, null, null, false, "ContentProvider not responding");
8689        } finally {
8690            Binder.restoreCallingIdentity(token);
8691        }
8692    }
8693
8694    public final void installSystemProviders() {
8695        List<ProviderInfo> providers;
8696        synchronized (this) {
8697            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8698            providers = generateApplicationProvidersLocked(app);
8699            if (providers != null) {
8700                for (int i=providers.size()-1; i>=0; i--) {
8701                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8702                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8703                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8704                                + ": not system .apk");
8705                        providers.remove(i);
8706                    }
8707                }
8708            }
8709        }
8710        if (providers != null) {
8711            mSystemThread.installSystemProviders(providers);
8712        }
8713
8714        mCoreSettingsObserver = new CoreSettingsObserver(this);
8715
8716        mUsageStatsService.monitorPackages();
8717    }
8718
8719    /**
8720     * Allows app to retrieve the MIME type of a URI without having permission
8721     * to access its content provider.
8722     *
8723     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8724     *
8725     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8726     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8727     */
8728    public String getProviderMimeType(Uri uri, int userId) {
8729        enforceNotIsolatedCaller("getProviderMimeType");
8730        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8731                userId, false, true, "getProviderMimeType", null);
8732        final String name = uri.getAuthority();
8733        final long ident = Binder.clearCallingIdentity();
8734        ContentProviderHolder holder = null;
8735
8736        try {
8737            holder = getContentProviderExternalUnchecked(name, null, userId);
8738            if (holder != null) {
8739                return holder.provider.getType(uri);
8740            }
8741        } catch (RemoteException e) {
8742            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8743            return null;
8744        } finally {
8745            if (holder != null) {
8746                removeContentProviderExternalUnchecked(name, null, userId);
8747            }
8748            Binder.restoreCallingIdentity(ident);
8749        }
8750
8751        return null;
8752    }
8753
8754    // =========================================================
8755    // GLOBAL MANAGEMENT
8756    // =========================================================
8757
8758    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8759            boolean isolated) {
8760        String proc = customProcess != null ? customProcess : info.processName;
8761        BatteryStatsImpl.Uid.Proc ps = null;
8762        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8763        int uid = info.uid;
8764        if (isolated) {
8765            int userId = UserHandle.getUserId(uid);
8766            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8767            while (true) {
8768                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8769                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8770                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8771                }
8772                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8773                mNextIsolatedProcessUid++;
8774                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8775                    // No process for this uid, use it.
8776                    break;
8777                }
8778                stepsLeft--;
8779                if (stepsLeft <= 0) {
8780                    return null;
8781                }
8782            }
8783        }
8784        return new ProcessRecord(stats, info, proc, uid);
8785    }
8786
8787    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8788            String abiOverride) {
8789        ProcessRecord app;
8790        if (!isolated) {
8791            app = getProcessRecordLocked(info.processName, info.uid, true);
8792        } else {
8793            app = null;
8794        }
8795
8796        if (app == null) {
8797            app = newProcessRecordLocked(info, null, isolated);
8798            mProcessNames.put(info.processName, app.uid, app);
8799            if (isolated) {
8800                mIsolatedProcesses.put(app.uid, app);
8801            }
8802            updateLruProcessLocked(app, false, null);
8803            updateOomAdjLocked();
8804        }
8805
8806        // This package really, really can not be stopped.
8807        try {
8808            AppGlobals.getPackageManager().setPackageStoppedState(
8809                    info.packageName, false, UserHandle.getUserId(app.uid));
8810        } catch (RemoteException e) {
8811        } catch (IllegalArgumentException e) {
8812            Slog.w(TAG, "Failed trying to unstop package "
8813                    + info.packageName + ": " + e);
8814        }
8815
8816        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8817                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8818            app.persistent = true;
8819            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8820        }
8821        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8822            mPersistentStartingProcesses.add(app);
8823            startProcessLocked(app, "added application", app.processName,
8824                    abiOverride);
8825        }
8826
8827        return app;
8828    }
8829
8830    public void unhandledBack() {
8831        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8832                "unhandledBack()");
8833
8834        synchronized(this) {
8835            final long origId = Binder.clearCallingIdentity();
8836            try {
8837                getFocusedStack().unhandledBackLocked();
8838            } finally {
8839                Binder.restoreCallingIdentity(origId);
8840            }
8841        }
8842    }
8843
8844    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8845        enforceNotIsolatedCaller("openContentUri");
8846        final int userId = UserHandle.getCallingUserId();
8847        String name = uri.getAuthority();
8848        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8849        ParcelFileDescriptor pfd = null;
8850        if (cph != null) {
8851            // We record the binder invoker's uid in thread-local storage before
8852            // going to the content provider to open the file.  Later, in the code
8853            // that handles all permissions checks, we look for this uid and use
8854            // that rather than the Activity Manager's own uid.  The effect is that
8855            // we do the check against the caller's permissions even though it looks
8856            // to the content provider like the Activity Manager itself is making
8857            // the request.
8858            sCallerIdentity.set(new Identity(
8859                    Binder.getCallingPid(), Binder.getCallingUid()));
8860            try {
8861                pfd = cph.provider.openFile(null, uri, "r", null);
8862            } catch (FileNotFoundException e) {
8863                // do nothing; pfd will be returned null
8864            } finally {
8865                // Ensure that whatever happens, we clean up the identity state
8866                sCallerIdentity.remove();
8867            }
8868
8869            // We've got the fd now, so we're done with the provider.
8870            removeContentProviderExternalUnchecked(name, null, userId);
8871        } else {
8872            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8873        }
8874        return pfd;
8875    }
8876
8877    // Actually is sleeping or shutting down or whatever else in the future
8878    // is an inactive state.
8879    public boolean isSleepingOrShuttingDown() {
8880        return mSleeping || mShuttingDown;
8881    }
8882
8883    public boolean isSleeping() {
8884        return mSleeping;
8885    }
8886
8887    void goingToSleep() {
8888        synchronized(this) {
8889            mWentToSleep = true;
8890            updateEventDispatchingLocked();
8891            goToSleepIfNeededLocked();
8892        }
8893    }
8894
8895    void finishRunningVoiceLocked() {
8896        if (mRunningVoice) {
8897            mRunningVoice = false;
8898            goToSleepIfNeededLocked();
8899        }
8900    }
8901
8902    void goToSleepIfNeededLocked() {
8903        if (mWentToSleep && !mRunningVoice) {
8904            if (!mSleeping) {
8905                mSleeping = true;
8906                mStackSupervisor.goingToSleepLocked();
8907
8908                // Initialize the wake times of all processes.
8909                checkExcessivePowerUsageLocked(false);
8910                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8911                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8912                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8913            }
8914        }
8915    }
8916
8917    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8918        mTaskPersister.notify(task, flush);
8919    }
8920
8921    @Override
8922    public boolean shutdown(int timeout) {
8923        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8924                != PackageManager.PERMISSION_GRANTED) {
8925            throw new SecurityException("Requires permission "
8926                    + android.Manifest.permission.SHUTDOWN);
8927        }
8928
8929        boolean timedout = false;
8930
8931        synchronized(this) {
8932            mShuttingDown = true;
8933            updateEventDispatchingLocked();
8934            timedout = mStackSupervisor.shutdownLocked(timeout);
8935        }
8936
8937        mAppOpsService.shutdown();
8938        mUsageStatsService.shutdown();
8939        mBatteryStatsService.shutdown();
8940        synchronized (this) {
8941            mProcessStats.shutdownLocked();
8942        }
8943        notifyTaskPersisterLocked(null, true);
8944
8945        return timedout;
8946    }
8947
8948    public final void activitySlept(IBinder token) {
8949        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8950
8951        final long origId = Binder.clearCallingIdentity();
8952
8953        synchronized (this) {
8954            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8955            if (r != null) {
8956                mStackSupervisor.activitySleptLocked(r);
8957            }
8958        }
8959
8960        Binder.restoreCallingIdentity(origId);
8961    }
8962
8963    void logLockScreen(String msg) {
8964        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8965                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8966                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8967                mStackSupervisor.mDismissKeyguardOnNextActivity);
8968    }
8969
8970    private void comeOutOfSleepIfNeededLocked() {
8971        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8972            if (mSleeping) {
8973                mSleeping = false;
8974                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8975            }
8976        }
8977    }
8978
8979    void wakingUp() {
8980        synchronized(this) {
8981            mWentToSleep = false;
8982            updateEventDispatchingLocked();
8983            comeOutOfSleepIfNeededLocked();
8984        }
8985    }
8986
8987    void startRunningVoiceLocked() {
8988        if (!mRunningVoice) {
8989            mRunningVoice = true;
8990            comeOutOfSleepIfNeededLocked();
8991        }
8992    }
8993
8994    private void updateEventDispatchingLocked() {
8995        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8996    }
8997
8998    public void setLockScreenShown(boolean shown) {
8999        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9000                != PackageManager.PERMISSION_GRANTED) {
9001            throw new SecurityException("Requires permission "
9002                    + android.Manifest.permission.DEVICE_POWER);
9003        }
9004
9005        synchronized(this) {
9006            long ident = Binder.clearCallingIdentity();
9007            try {
9008                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9009                mLockScreenShown = shown;
9010                comeOutOfSleepIfNeededLocked();
9011            } finally {
9012                Binder.restoreCallingIdentity(ident);
9013            }
9014        }
9015    }
9016
9017    public void stopAppSwitches() {
9018        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9019                != PackageManager.PERMISSION_GRANTED) {
9020            throw new SecurityException("Requires permission "
9021                    + android.Manifest.permission.STOP_APP_SWITCHES);
9022        }
9023
9024        synchronized(this) {
9025            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9026                    + APP_SWITCH_DELAY_TIME;
9027            mDidAppSwitch = false;
9028            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9029            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9030            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9031        }
9032    }
9033
9034    public void resumeAppSwitches() {
9035        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9036                != PackageManager.PERMISSION_GRANTED) {
9037            throw new SecurityException("Requires permission "
9038                    + android.Manifest.permission.STOP_APP_SWITCHES);
9039        }
9040
9041        synchronized(this) {
9042            // Note that we don't execute any pending app switches... we will
9043            // let those wait until either the timeout, or the next start
9044            // activity request.
9045            mAppSwitchesAllowedTime = 0;
9046        }
9047    }
9048
9049    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9050            String name) {
9051        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9052            return true;
9053        }
9054
9055        final int perm = checkComponentPermission(
9056                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9057                callingUid, -1, true);
9058        if (perm == PackageManager.PERMISSION_GRANTED) {
9059            return true;
9060        }
9061
9062        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9063        return false;
9064    }
9065
9066    public void setDebugApp(String packageName, boolean waitForDebugger,
9067            boolean persistent) {
9068        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9069                "setDebugApp()");
9070
9071        long ident = Binder.clearCallingIdentity();
9072        try {
9073            // Note that this is not really thread safe if there are multiple
9074            // callers into it at the same time, but that's not a situation we
9075            // care about.
9076            if (persistent) {
9077                final ContentResolver resolver = mContext.getContentResolver();
9078                Settings.Global.putString(
9079                    resolver, Settings.Global.DEBUG_APP,
9080                    packageName);
9081                Settings.Global.putInt(
9082                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9083                    waitForDebugger ? 1 : 0);
9084            }
9085
9086            synchronized (this) {
9087                if (!persistent) {
9088                    mOrigDebugApp = mDebugApp;
9089                    mOrigWaitForDebugger = mWaitForDebugger;
9090                }
9091                mDebugApp = packageName;
9092                mWaitForDebugger = waitForDebugger;
9093                mDebugTransient = !persistent;
9094                if (packageName != null) {
9095                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9096                            false, UserHandle.USER_ALL, "set debug app");
9097                }
9098            }
9099        } finally {
9100            Binder.restoreCallingIdentity(ident);
9101        }
9102    }
9103
9104    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9105        synchronized (this) {
9106            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9107            if (!isDebuggable) {
9108                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9109                    throw new SecurityException("Process not debuggable: " + app.packageName);
9110                }
9111            }
9112
9113            mOpenGlTraceApp = processName;
9114        }
9115    }
9116
9117    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9118            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9119        synchronized (this) {
9120            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9121            if (!isDebuggable) {
9122                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9123                    throw new SecurityException("Process not debuggable: " + app.packageName);
9124                }
9125            }
9126            mProfileApp = processName;
9127            mProfileFile = profileFile;
9128            if (mProfileFd != null) {
9129                try {
9130                    mProfileFd.close();
9131                } catch (IOException e) {
9132                }
9133                mProfileFd = null;
9134            }
9135            mProfileFd = profileFd;
9136            mProfileType = 0;
9137            mAutoStopProfiler = autoStopProfiler;
9138        }
9139    }
9140
9141    @Override
9142    public void setAlwaysFinish(boolean enabled) {
9143        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9144                "setAlwaysFinish()");
9145
9146        Settings.Global.putInt(
9147                mContext.getContentResolver(),
9148                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9149
9150        synchronized (this) {
9151            mAlwaysFinishActivities = enabled;
9152        }
9153    }
9154
9155    @Override
9156    public void setActivityController(IActivityController controller) {
9157        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9158                "setActivityController()");
9159        synchronized (this) {
9160            mController = controller;
9161            Watchdog.getInstance().setActivityController(controller);
9162        }
9163    }
9164
9165    @Override
9166    public void setUserIsMonkey(boolean userIsMonkey) {
9167        synchronized (this) {
9168            synchronized (mPidsSelfLocked) {
9169                final int callingPid = Binder.getCallingPid();
9170                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9171                if (precessRecord == null) {
9172                    throw new SecurityException("Unknown process: " + callingPid);
9173                }
9174                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9175                    throw new SecurityException("Only an instrumentation process "
9176                            + "with a UiAutomation can call setUserIsMonkey");
9177                }
9178            }
9179            mUserIsMonkey = userIsMonkey;
9180        }
9181    }
9182
9183    @Override
9184    public boolean isUserAMonkey() {
9185        synchronized (this) {
9186            // If there is a controller also implies the user is a monkey.
9187            return (mUserIsMonkey || mController != null);
9188        }
9189    }
9190
9191    public void requestBugReport() {
9192        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9193        SystemProperties.set("ctl.start", "bugreport");
9194    }
9195
9196    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9197        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9198    }
9199
9200    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9201        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9202            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9203        }
9204        return KEY_DISPATCHING_TIMEOUT;
9205    }
9206
9207    @Override
9208    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9209        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9210                != PackageManager.PERMISSION_GRANTED) {
9211            throw new SecurityException("Requires permission "
9212                    + android.Manifest.permission.FILTER_EVENTS);
9213        }
9214        ProcessRecord proc;
9215        long timeout;
9216        synchronized (this) {
9217            synchronized (mPidsSelfLocked) {
9218                proc = mPidsSelfLocked.get(pid);
9219            }
9220            timeout = getInputDispatchingTimeoutLocked(proc);
9221        }
9222
9223        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9224            return -1;
9225        }
9226
9227        return timeout;
9228    }
9229
9230    /**
9231     * Handle input dispatching timeouts.
9232     * Returns whether input dispatching should be aborted or not.
9233     */
9234    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9235            final ActivityRecord activity, final ActivityRecord parent,
9236            final boolean aboveSystem, String reason) {
9237        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9238                != PackageManager.PERMISSION_GRANTED) {
9239            throw new SecurityException("Requires permission "
9240                    + android.Manifest.permission.FILTER_EVENTS);
9241        }
9242
9243        final String annotation;
9244        if (reason == null) {
9245            annotation = "Input dispatching timed out";
9246        } else {
9247            annotation = "Input dispatching timed out (" + reason + ")";
9248        }
9249
9250        if (proc != null) {
9251            synchronized (this) {
9252                if (proc.debugging) {
9253                    return false;
9254                }
9255
9256                if (mDidDexOpt) {
9257                    // Give more time since we were dexopting.
9258                    mDidDexOpt = false;
9259                    return false;
9260                }
9261
9262                if (proc.instrumentationClass != null) {
9263                    Bundle info = new Bundle();
9264                    info.putString("shortMsg", "keyDispatchingTimedOut");
9265                    info.putString("longMsg", annotation);
9266                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9267                    return true;
9268                }
9269            }
9270            mHandler.post(new Runnable() {
9271                @Override
9272                public void run() {
9273                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9274                }
9275            });
9276        }
9277
9278        return true;
9279    }
9280
9281    public Bundle getAssistContextExtras(int requestType) {
9282        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9283                "getAssistContextExtras()");
9284        PendingAssistExtras pae;
9285        Bundle extras = new Bundle();
9286        synchronized (this) {
9287            ActivityRecord activity = getFocusedStack().mResumedActivity;
9288            if (activity == null) {
9289                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9290                return null;
9291            }
9292            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9293            if (activity.app == null || activity.app.thread == null) {
9294                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9295                return extras;
9296            }
9297            if (activity.app.pid == Binder.getCallingPid()) {
9298                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9299                return extras;
9300            }
9301            pae = new PendingAssistExtras(activity);
9302            try {
9303                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9304                        requestType);
9305                mPendingAssistExtras.add(pae);
9306                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9307            } catch (RemoteException e) {
9308                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9309                return extras;
9310            }
9311        }
9312        synchronized (pae) {
9313            while (!pae.haveResult) {
9314                try {
9315                    pae.wait();
9316                } catch (InterruptedException e) {
9317                }
9318            }
9319            if (pae.result != null) {
9320                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9321            }
9322        }
9323        synchronized (this) {
9324            mPendingAssistExtras.remove(pae);
9325            mHandler.removeCallbacks(pae);
9326        }
9327        return extras;
9328    }
9329
9330    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9331        PendingAssistExtras pae = (PendingAssistExtras)token;
9332        synchronized (pae) {
9333            pae.result = extras;
9334            pae.haveResult = true;
9335            pae.notifyAll();
9336        }
9337    }
9338
9339    public void registerProcessObserver(IProcessObserver observer) {
9340        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9341                "registerProcessObserver()");
9342        synchronized (this) {
9343            mProcessObservers.register(observer);
9344        }
9345    }
9346
9347    @Override
9348    public void unregisterProcessObserver(IProcessObserver observer) {
9349        synchronized (this) {
9350            mProcessObservers.unregister(observer);
9351        }
9352    }
9353
9354    @Override
9355    public boolean convertFromTranslucent(IBinder token) {
9356        final long origId = Binder.clearCallingIdentity();
9357        try {
9358            synchronized (this) {
9359                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9360                if (r == null) {
9361                    return false;
9362                }
9363                if (r.changeWindowTranslucency(true)) {
9364                    mWindowManager.setAppFullscreen(token, true);
9365                    r.task.stack.releaseMediaResources();
9366                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9367                    return true;
9368                }
9369                return false;
9370            }
9371        } finally {
9372            Binder.restoreCallingIdentity(origId);
9373        }
9374    }
9375
9376    @Override
9377    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9378        final long origId = Binder.clearCallingIdentity();
9379        try {
9380            synchronized (this) {
9381                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9382                if (r == null) {
9383                    return false;
9384                }
9385                if (r.changeWindowTranslucency(false)) {
9386                    r.task.stack.convertToTranslucent(r, options);
9387                    mWindowManager.setAppFullscreen(token, false);
9388                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9389                    return true;
9390                } else {
9391                    r.task.stack.mReturningActivityOptions = options;
9392                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9393                    return false;
9394                }
9395            }
9396        } finally {
9397            Binder.restoreCallingIdentity(origId);
9398        }
9399    }
9400
9401    @Override
9402    public boolean setMediaPlaying(IBinder token, boolean playing) {
9403        final long origId = Binder.clearCallingIdentity();
9404        try {
9405            synchronized (this) {
9406                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9407                if (r != null) {
9408                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9409                }
9410            }
9411            return false;
9412        } finally {
9413            Binder.restoreCallingIdentity(origId);
9414        }
9415    }
9416
9417    @Override
9418    public boolean isBackgroundMediaPlaying(IBinder token) {
9419        final long origId = Binder.clearCallingIdentity();
9420        try {
9421            synchronized (this) {
9422                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9423                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9424                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9425                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9426                return playing;
9427            }
9428        } finally {
9429            Binder.restoreCallingIdentity(origId);
9430        }
9431    }
9432
9433    @Override
9434    public ActivityOptions getActivityOptions(IBinder token) {
9435        final long origId = Binder.clearCallingIdentity();
9436        try {
9437            synchronized (this) {
9438                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9439                if (r != null) {
9440                    final ActivityOptions activityOptions = r.pendingOptions;
9441                    r.pendingOptions = null;
9442                    return activityOptions;
9443                }
9444                return null;
9445            }
9446        } finally {
9447            Binder.restoreCallingIdentity(origId);
9448        }
9449    }
9450
9451    @Override
9452    public void setImmersive(IBinder token, boolean immersive) {
9453        synchronized(this) {
9454            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9455            if (r == null) {
9456                throw new IllegalArgumentException();
9457            }
9458            r.immersive = immersive;
9459
9460            // update associated state if we're frontmost
9461            if (r == mFocusedActivity) {
9462                if (DEBUG_IMMERSIVE) {
9463                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9464                }
9465                applyUpdateLockStateLocked(r);
9466            }
9467        }
9468    }
9469
9470    @Override
9471    public boolean isImmersive(IBinder token) {
9472        synchronized (this) {
9473            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9474            if (r == null) {
9475                throw new IllegalArgumentException();
9476            }
9477            return r.immersive;
9478        }
9479    }
9480
9481    public boolean isTopActivityImmersive() {
9482        enforceNotIsolatedCaller("startActivity");
9483        synchronized (this) {
9484            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9485            return (r != null) ? r.immersive : false;
9486        }
9487    }
9488
9489    @Override
9490    public boolean isTopOfTask(IBinder token) {
9491        synchronized (this) {
9492            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9493            if (r == null) {
9494                throw new IllegalArgumentException();
9495            }
9496            return r.task.getTopActivity() == r;
9497        }
9498    }
9499
9500    public final void enterSafeMode() {
9501        synchronized(this) {
9502            // It only makes sense to do this before the system is ready
9503            // and started launching other packages.
9504            if (!mSystemReady) {
9505                try {
9506                    AppGlobals.getPackageManager().enterSafeMode();
9507                } catch (RemoteException e) {
9508                }
9509            }
9510
9511            mSafeMode = true;
9512        }
9513    }
9514
9515    public final void showSafeModeOverlay() {
9516        View v = LayoutInflater.from(mContext).inflate(
9517                com.android.internal.R.layout.safe_mode, null);
9518        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9519        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9520        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9521        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9522        lp.gravity = Gravity.BOTTOM | Gravity.START;
9523        lp.format = v.getBackground().getOpacity();
9524        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9525                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9526        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9527        ((WindowManager)mContext.getSystemService(
9528                Context.WINDOW_SERVICE)).addView(v, lp);
9529    }
9530
9531    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9532        if (!(sender instanceof PendingIntentRecord)) {
9533            return;
9534        }
9535        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9536        synchronized (stats) {
9537            if (mBatteryStatsService.isOnBattery()) {
9538                mBatteryStatsService.enforceCallingPermission();
9539                PendingIntentRecord rec = (PendingIntentRecord)sender;
9540                int MY_UID = Binder.getCallingUid();
9541                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9542                BatteryStatsImpl.Uid.Pkg pkg =
9543                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9544                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9545                pkg.incWakeupsLocked();
9546            }
9547        }
9548    }
9549
9550    public boolean killPids(int[] pids, String pReason, boolean secure) {
9551        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9552            throw new SecurityException("killPids only available to the system");
9553        }
9554        String reason = (pReason == null) ? "Unknown" : pReason;
9555        // XXX Note: don't acquire main activity lock here, because the window
9556        // manager calls in with its locks held.
9557
9558        boolean killed = false;
9559        synchronized (mPidsSelfLocked) {
9560            int[] types = new int[pids.length];
9561            int worstType = 0;
9562            for (int i=0; i<pids.length; i++) {
9563                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9564                if (proc != null) {
9565                    int type = proc.setAdj;
9566                    types[i] = type;
9567                    if (type > worstType) {
9568                        worstType = type;
9569                    }
9570                }
9571            }
9572
9573            // If the worst oom_adj is somewhere in the cached proc LRU range,
9574            // then constrain it so we will kill all cached procs.
9575            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9576                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9577                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9578            }
9579
9580            // If this is not a secure call, don't let it kill processes that
9581            // are important.
9582            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9583                worstType = ProcessList.SERVICE_ADJ;
9584            }
9585
9586            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9587            for (int i=0; i<pids.length; i++) {
9588                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9589                if (proc == null) {
9590                    continue;
9591                }
9592                int adj = proc.setAdj;
9593                if (adj >= worstType && !proc.killedByAm) {
9594                    killUnneededProcessLocked(proc, reason);
9595                    killed = true;
9596                }
9597            }
9598        }
9599        return killed;
9600    }
9601
9602    @Override
9603    public void killUid(int uid, String reason) {
9604        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9605            throw new SecurityException("killUid only available to the system");
9606        }
9607        synchronized (this) {
9608            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9609                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9610                    reason != null ? reason : "kill uid");
9611        }
9612    }
9613
9614    @Override
9615    public boolean killProcessesBelowForeground(String reason) {
9616        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9617            throw new SecurityException("killProcessesBelowForeground() only available to system");
9618        }
9619
9620        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9621    }
9622
9623    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9624        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9625            throw new SecurityException("killProcessesBelowAdj() only available to system");
9626        }
9627
9628        boolean killed = false;
9629        synchronized (mPidsSelfLocked) {
9630            final int size = mPidsSelfLocked.size();
9631            for (int i = 0; i < size; i++) {
9632                final int pid = mPidsSelfLocked.keyAt(i);
9633                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9634                if (proc == null) continue;
9635
9636                final int adj = proc.setAdj;
9637                if (adj > belowAdj && !proc.killedByAm) {
9638                    killUnneededProcessLocked(proc, reason);
9639                    killed = true;
9640                }
9641            }
9642        }
9643        return killed;
9644    }
9645
9646    @Override
9647    public void hang(final IBinder who, boolean allowRestart) {
9648        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9649                != PackageManager.PERMISSION_GRANTED) {
9650            throw new SecurityException("Requires permission "
9651                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9652        }
9653
9654        final IBinder.DeathRecipient death = new DeathRecipient() {
9655            @Override
9656            public void binderDied() {
9657                synchronized (this) {
9658                    notifyAll();
9659                }
9660            }
9661        };
9662
9663        try {
9664            who.linkToDeath(death, 0);
9665        } catch (RemoteException e) {
9666            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9667            return;
9668        }
9669
9670        synchronized (this) {
9671            Watchdog.getInstance().setAllowRestart(allowRestart);
9672            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9673            synchronized (death) {
9674                while (who.isBinderAlive()) {
9675                    try {
9676                        death.wait();
9677                    } catch (InterruptedException e) {
9678                    }
9679                }
9680            }
9681            Watchdog.getInstance().setAllowRestart(true);
9682        }
9683    }
9684
9685    @Override
9686    public void restart() {
9687        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9688                != PackageManager.PERMISSION_GRANTED) {
9689            throw new SecurityException("Requires permission "
9690                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9691        }
9692
9693        Log.i(TAG, "Sending shutdown broadcast...");
9694
9695        BroadcastReceiver br = new BroadcastReceiver() {
9696            @Override public void onReceive(Context context, Intent intent) {
9697                // Now the broadcast is done, finish up the low-level shutdown.
9698                Log.i(TAG, "Shutting down activity manager...");
9699                shutdown(10000);
9700                Log.i(TAG, "Shutdown complete, restarting!");
9701                Process.killProcess(Process.myPid());
9702                System.exit(10);
9703            }
9704        };
9705
9706        // First send the high-level shut down broadcast.
9707        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9708        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9709        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9710        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9711        mContext.sendOrderedBroadcastAsUser(intent,
9712                UserHandle.ALL, null, br, mHandler, 0, null, null);
9713        */
9714        br.onReceive(mContext, intent);
9715    }
9716
9717    private long getLowRamTimeSinceIdle(long now) {
9718        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9719    }
9720
9721    @Override
9722    public void performIdleMaintenance() {
9723        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9724                != PackageManager.PERMISSION_GRANTED) {
9725            throw new SecurityException("Requires permission "
9726                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9727        }
9728
9729        synchronized (this) {
9730            final long now = SystemClock.uptimeMillis();
9731            final long timeSinceLastIdle = now - mLastIdleTime;
9732            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9733            mLastIdleTime = now;
9734            mLowRamTimeSinceLastIdle = 0;
9735            if (mLowRamStartTime != 0) {
9736                mLowRamStartTime = now;
9737            }
9738
9739            StringBuilder sb = new StringBuilder(128);
9740            sb.append("Idle maintenance over ");
9741            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9742            sb.append(" low RAM for ");
9743            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9744            Slog.i(TAG, sb.toString());
9745
9746            // If at least 1/3 of our time since the last idle period has been spent
9747            // with RAM low, then we want to kill processes.
9748            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9749
9750            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9751                ProcessRecord proc = mLruProcesses.get(i);
9752                if (proc.notCachedSinceIdle) {
9753                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9754                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9755                        if (doKilling && proc.initialIdlePss != 0
9756                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9757                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9758                                    + " from " + proc.initialIdlePss + ")");
9759                        }
9760                    }
9761                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9762                    proc.notCachedSinceIdle = true;
9763                    proc.initialIdlePss = 0;
9764                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9765                            isSleeping(), now);
9766                }
9767            }
9768
9769            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9770            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9771        }
9772    }
9773
9774    private void retrieveSettings() {
9775        final ContentResolver resolver = mContext.getContentResolver();
9776        String debugApp = Settings.Global.getString(
9777            resolver, Settings.Global.DEBUG_APP);
9778        boolean waitForDebugger = Settings.Global.getInt(
9779            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9780        boolean alwaysFinishActivities = Settings.Global.getInt(
9781            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9782        boolean forceRtl = Settings.Global.getInt(
9783                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9784        // Transfer any global setting for forcing RTL layout, into a System Property
9785        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9786
9787        Configuration configuration = new Configuration();
9788        Settings.System.getConfiguration(resolver, configuration);
9789        if (forceRtl) {
9790            // This will take care of setting the correct layout direction flags
9791            configuration.setLayoutDirection(configuration.locale);
9792        }
9793
9794        synchronized (this) {
9795            mDebugApp = mOrigDebugApp = debugApp;
9796            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9797            mAlwaysFinishActivities = alwaysFinishActivities;
9798            // This happens before any activities are started, so we can
9799            // change mConfiguration in-place.
9800            updateConfigurationLocked(configuration, null, false, true);
9801            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9802        }
9803    }
9804
9805    public boolean testIsSystemReady() {
9806        // no need to synchronize(this) just to read & return the value
9807        return mSystemReady;
9808    }
9809
9810    private static File getCalledPreBootReceiversFile() {
9811        File dataDir = Environment.getDataDirectory();
9812        File systemDir = new File(dataDir, "system");
9813        File fname = new File(systemDir, "called_pre_boots.dat");
9814        return fname;
9815    }
9816
9817    static final int LAST_DONE_VERSION = 10000;
9818
9819    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9820        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9821        File file = getCalledPreBootReceiversFile();
9822        FileInputStream fis = null;
9823        try {
9824            fis = new FileInputStream(file);
9825            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9826            int fvers = dis.readInt();
9827            if (fvers == LAST_DONE_VERSION) {
9828                String vers = dis.readUTF();
9829                String codename = dis.readUTF();
9830                String build = dis.readUTF();
9831                if (android.os.Build.VERSION.RELEASE.equals(vers)
9832                        && android.os.Build.VERSION.CODENAME.equals(codename)
9833                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9834                    int num = dis.readInt();
9835                    while (num > 0) {
9836                        num--;
9837                        String pkg = dis.readUTF();
9838                        String cls = dis.readUTF();
9839                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9840                    }
9841                }
9842            }
9843        } catch (FileNotFoundException e) {
9844        } catch (IOException e) {
9845            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9846        } finally {
9847            if (fis != null) {
9848                try {
9849                    fis.close();
9850                } catch (IOException e) {
9851                }
9852            }
9853        }
9854        return lastDoneReceivers;
9855    }
9856
9857    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9858        File file = getCalledPreBootReceiversFile();
9859        FileOutputStream fos = null;
9860        DataOutputStream dos = null;
9861        try {
9862            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9863            fos = new FileOutputStream(file);
9864            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9865            dos.writeInt(LAST_DONE_VERSION);
9866            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9867            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9868            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9869            dos.writeInt(list.size());
9870            for (int i=0; i<list.size(); i++) {
9871                dos.writeUTF(list.get(i).getPackageName());
9872                dos.writeUTF(list.get(i).getClassName());
9873            }
9874        } catch (IOException e) {
9875            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9876            file.delete();
9877        } finally {
9878            FileUtils.sync(fos);
9879            if (dos != null) {
9880                try {
9881                    dos.close();
9882                } catch (IOException e) {
9883                    // TODO Auto-generated catch block
9884                    e.printStackTrace();
9885                }
9886            }
9887        }
9888    }
9889
9890    public void systemReady(final Runnable goingCallback) {
9891        synchronized(this) {
9892            if (mSystemReady) {
9893                if (goingCallback != null) goingCallback.run();
9894                return;
9895            }
9896
9897            if (mRecentTasks == null) {
9898                mRecentTasks = mTaskPersister.restoreTasksLocked();
9899                if (!mRecentTasks.isEmpty()) {
9900                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9901                }
9902                mTaskPersister.startPersisting();
9903            }
9904
9905            // Check to see if there are any update receivers to run.
9906            if (!mDidUpdate) {
9907                if (mWaitingUpdate) {
9908                    return;
9909                }
9910                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9911                List<ResolveInfo> ris = null;
9912                try {
9913                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9914                            intent, null, 0, 0);
9915                } catch (RemoteException e) {
9916                }
9917                if (ris != null) {
9918                    for (int i=ris.size()-1; i>=0; i--) {
9919                        if ((ris.get(i).activityInfo.applicationInfo.flags
9920                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9921                            ris.remove(i);
9922                        }
9923                    }
9924                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9925
9926                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9927
9928                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9929                    for (int i=0; i<ris.size(); i++) {
9930                        ActivityInfo ai = ris.get(i).activityInfo;
9931                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9932                        if (lastDoneReceivers.contains(comp)) {
9933                            // We already did the pre boot receiver for this app with the current
9934                            // platform version, so don't do it again...
9935                            ris.remove(i);
9936                            i--;
9937                            // ...however, do keep it as one that has been done, so we don't
9938                            // forget about it when rewriting the file of last done receivers.
9939                            doneReceivers.add(comp);
9940                        }
9941                    }
9942
9943                    final int[] users = getUsersLocked();
9944                    for (int i=0; i<ris.size(); i++) {
9945                        ActivityInfo ai = ris.get(i).activityInfo;
9946                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9947                        doneReceivers.add(comp);
9948                        intent.setComponent(comp);
9949                        for (int j=0; j<users.length; j++) {
9950                            IIntentReceiver finisher = null;
9951                            if (i == ris.size()-1 && j == users.length-1) {
9952                                finisher = new IIntentReceiver.Stub() {
9953                                    public void performReceive(Intent intent, int resultCode,
9954                                            String data, Bundle extras, boolean ordered,
9955                                            boolean sticky, int sendingUser) {
9956                                        // The raw IIntentReceiver interface is called
9957                                        // with the AM lock held, so redispatch to
9958                                        // execute our code without the lock.
9959                                        mHandler.post(new Runnable() {
9960                                            public void run() {
9961                                                synchronized (ActivityManagerService.this) {
9962                                                    mDidUpdate = true;
9963                                                }
9964                                                writeLastDonePreBootReceivers(doneReceivers);
9965                                                showBootMessage(mContext.getText(
9966                                                        R.string.android_upgrading_complete),
9967                                                        false);
9968                                                systemReady(goingCallback);
9969                                            }
9970                                        });
9971                                    }
9972                                };
9973                            }
9974                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9975                                    + " for user " + users[j]);
9976                            broadcastIntentLocked(null, null, intent, null, finisher,
9977                                    0, null, null, null, AppOpsManager.OP_NONE,
9978                                    true, false, MY_PID, Process.SYSTEM_UID,
9979                                    users[j]);
9980                            if (finisher != null) {
9981                                mWaitingUpdate = true;
9982                            }
9983                        }
9984                    }
9985                }
9986                if (mWaitingUpdate) {
9987                    return;
9988                }
9989                mDidUpdate = true;
9990            }
9991
9992            mAppOpsService.systemReady();
9993            mUsageStatsService.systemReady();
9994            mSystemReady = true;
9995        }
9996
9997        ArrayList<ProcessRecord> procsToKill = null;
9998        synchronized(mPidsSelfLocked) {
9999            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10000                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10001                if (!isAllowedWhileBooting(proc.info)){
10002                    if (procsToKill == null) {
10003                        procsToKill = new ArrayList<ProcessRecord>();
10004                    }
10005                    procsToKill.add(proc);
10006                }
10007            }
10008        }
10009
10010        synchronized(this) {
10011            if (procsToKill != null) {
10012                for (int i=procsToKill.size()-1; i>=0; i--) {
10013                    ProcessRecord proc = procsToKill.get(i);
10014                    Slog.i(TAG, "Removing system update proc: " + proc);
10015                    removeProcessLocked(proc, true, false, "system update done");
10016                }
10017            }
10018
10019            // Now that we have cleaned up any update processes, we
10020            // are ready to start launching real processes and know that
10021            // we won't trample on them any more.
10022            mProcessesReady = true;
10023        }
10024
10025        Slog.i(TAG, "System now ready");
10026        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10027            SystemClock.uptimeMillis());
10028
10029        synchronized(this) {
10030            // Make sure we have no pre-ready processes sitting around.
10031
10032            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10033                ResolveInfo ri = mContext.getPackageManager()
10034                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10035                                STOCK_PM_FLAGS);
10036                CharSequence errorMsg = null;
10037                if (ri != null) {
10038                    ActivityInfo ai = ri.activityInfo;
10039                    ApplicationInfo app = ai.applicationInfo;
10040                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10041                        mTopAction = Intent.ACTION_FACTORY_TEST;
10042                        mTopData = null;
10043                        mTopComponent = new ComponentName(app.packageName,
10044                                ai.name);
10045                    } else {
10046                        errorMsg = mContext.getResources().getText(
10047                                com.android.internal.R.string.factorytest_not_system);
10048                    }
10049                } else {
10050                    errorMsg = mContext.getResources().getText(
10051                            com.android.internal.R.string.factorytest_no_action);
10052                }
10053                if (errorMsg != null) {
10054                    mTopAction = null;
10055                    mTopData = null;
10056                    mTopComponent = null;
10057                    Message msg = Message.obtain();
10058                    msg.what = SHOW_FACTORY_ERROR_MSG;
10059                    msg.getData().putCharSequence("msg", errorMsg);
10060                    mHandler.sendMessage(msg);
10061                }
10062            }
10063        }
10064
10065        retrieveSettings();
10066
10067        synchronized (this) {
10068            readGrantedUriPermissionsLocked();
10069        }
10070
10071        if (goingCallback != null) goingCallback.run();
10072
10073        mSystemServiceManager.startUser(mCurrentUserId);
10074
10075        synchronized (this) {
10076            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10077                try {
10078                    List apps = AppGlobals.getPackageManager().
10079                        getPersistentApplications(STOCK_PM_FLAGS);
10080                    if (apps != null) {
10081                        int N = apps.size();
10082                        int i;
10083                        for (i=0; i<N; i++) {
10084                            ApplicationInfo info
10085                                = (ApplicationInfo)apps.get(i);
10086                            if (info != null &&
10087                                    !info.packageName.equals("android")) {
10088                                addAppLocked(info, false, null /* ABI override */);
10089                            }
10090                        }
10091                    }
10092                } catch (RemoteException ex) {
10093                    // pm is in same process, this will never happen.
10094                }
10095            }
10096
10097            // Start up initial activity.
10098            mBooting = true;
10099
10100            try {
10101                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10102                    Message msg = Message.obtain();
10103                    msg.what = SHOW_UID_ERROR_MSG;
10104                    mHandler.sendMessage(msg);
10105                }
10106            } catch (RemoteException e) {
10107            }
10108
10109            long ident = Binder.clearCallingIdentity();
10110            try {
10111                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10112                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10113                        | Intent.FLAG_RECEIVER_FOREGROUND);
10114                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10115                broadcastIntentLocked(null, null, intent,
10116                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10117                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10118                intent = new Intent(Intent.ACTION_USER_STARTING);
10119                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10120                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10121                broadcastIntentLocked(null, null, intent,
10122                        null, new IIntentReceiver.Stub() {
10123                            @Override
10124                            public void performReceive(Intent intent, int resultCode, String data,
10125                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10126                                    throws RemoteException {
10127                            }
10128                        }, 0, null, null,
10129                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10130                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10131            } catch (Throwable t) {
10132                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10133            } finally {
10134                Binder.restoreCallingIdentity(ident);
10135            }
10136            mStackSupervisor.resumeTopActivitiesLocked();
10137            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10138        }
10139    }
10140
10141    private boolean makeAppCrashingLocked(ProcessRecord app,
10142            String shortMsg, String longMsg, String stackTrace) {
10143        app.crashing = true;
10144        app.crashingReport = generateProcessError(app,
10145                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10146        startAppProblemLocked(app);
10147        app.stopFreezingAllLocked();
10148        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10149    }
10150
10151    private void makeAppNotRespondingLocked(ProcessRecord app,
10152            String activity, String shortMsg, String longMsg) {
10153        app.notResponding = true;
10154        app.notRespondingReport = generateProcessError(app,
10155                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10156                activity, shortMsg, longMsg, null);
10157        startAppProblemLocked(app);
10158        app.stopFreezingAllLocked();
10159    }
10160
10161    /**
10162     * Generate a process error record, suitable for attachment to a ProcessRecord.
10163     *
10164     * @param app The ProcessRecord in which the error occurred.
10165     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10166     *                      ActivityManager.AppErrorStateInfo
10167     * @param activity The activity associated with the crash, if known.
10168     * @param shortMsg Short message describing the crash.
10169     * @param longMsg Long message describing the crash.
10170     * @param stackTrace Full crash stack trace, may be null.
10171     *
10172     * @return Returns a fully-formed AppErrorStateInfo record.
10173     */
10174    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10175            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10176        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10177
10178        report.condition = condition;
10179        report.processName = app.processName;
10180        report.pid = app.pid;
10181        report.uid = app.info.uid;
10182        report.tag = activity;
10183        report.shortMsg = shortMsg;
10184        report.longMsg = longMsg;
10185        report.stackTrace = stackTrace;
10186
10187        return report;
10188    }
10189
10190    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10191        synchronized (this) {
10192            app.crashing = false;
10193            app.crashingReport = null;
10194            app.notResponding = false;
10195            app.notRespondingReport = null;
10196            if (app.anrDialog == fromDialog) {
10197                app.anrDialog = null;
10198            }
10199            if (app.waitDialog == fromDialog) {
10200                app.waitDialog = null;
10201            }
10202            if (app.pid > 0 && app.pid != MY_PID) {
10203                handleAppCrashLocked(app, null, null, null);
10204                killUnneededProcessLocked(app, "user request after error");
10205            }
10206        }
10207    }
10208
10209    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10210            String stackTrace) {
10211        long now = SystemClock.uptimeMillis();
10212
10213        Long crashTime;
10214        if (!app.isolated) {
10215            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10216        } else {
10217            crashTime = null;
10218        }
10219        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10220            // This process loses!
10221            Slog.w(TAG, "Process " + app.info.processName
10222                    + " has crashed too many times: killing!");
10223            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10224                    app.userId, app.info.processName, app.uid);
10225            mStackSupervisor.handleAppCrashLocked(app);
10226            if (!app.persistent) {
10227                // We don't want to start this process again until the user
10228                // explicitly does so...  but for persistent process, we really
10229                // need to keep it running.  If a persistent process is actually
10230                // repeatedly crashing, then badness for everyone.
10231                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10232                        app.info.processName);
10233                if (!app.isolated) {
10234                    // XXX We don't have a way to mark isolated processes
10235                    // as bad, since they don't have a peristent identity.
10236                    mBadProcesses.put(app.info.processName, app.uid,
10237                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10238                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10239                }
10240                app.bad = true;
10241                app.removed = true;
10242                // Don't let services in this process be restarted and potentially
10243                // annoy the user repeatedly.  Unless it is persistent, since those
10244                // processes run critical code.
10245                removeProcessLocked(app, false, false, "crash");
10246                mStackSupervisor.resumeTopActivitiesLocked();
10247                return false;
10248            }
10249            mStackSupervisor.resumeTopActivitiesLocked();
10250        } else {
10251            mStackSupervisor.finishTopRunningActivityLocked(app);
10252        }
10253
10254        // Bump up the crash count of any services currently running in the proc.
10255        for (int i=app.services.size()-1; i>=0; i--) {
10256            // Any services running in the application need to be placed
10257            // back in the pending list.
10258            ServiceRecord sr = app.services.valueAt(i);
10259            sr.crashCount++;
10260        }
10261
10262        // If the crashing process is what we consider to be the "home process" and it has been
10263        // replaced by a third-party app, clear the package preferred activities from packages
10264        // with a home activity running in the process to prevent a repeatedly crashing app
10265        // from blocking the user to manually clear the list.
10266        final ArrayList<ActivityRecord> activities = app.activities;
10267        if (app == mHomeProcess && activities.size() > 0
10268                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10269            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10270                final ActivityRecord r = activities.get(activityNdx);
10271                if (r.isHomeActivity()) {
10272                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10273                    try {
10274                        ActivityThread.getPackageManager()
10275                                .clearPackagePreferredActivities(r.packageName);
10276                    } catch (RemoteException c) {
10277                        // pm is in same process, this will never happen.
10278                    }
10279                }
10280            }
10281        }
10282
10283        if (!app.isolated) {
10284            // XXX Can't keep track of crash times for isolated processes,
10285            // because they don't have a perisistent identity.
10286            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10287        }
10288
10289        return true;
10290    }
10291
10292    void startAppProblemLocked(ProcessRecord app) {
10293        if (app.userId == mCurrentUserId) {
10294            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10295                    mContext, app.info.packageName, app.info.flags);
10296        } else {
10297            // If this app is not running under the current user, then we
10298            // can't give it a report button because that would require
10299            // launching the report UI under a different user.
10300            app.errorReportReceiver = null;
10301        }
10302        skipCurrentReceiverLocked(app);
10303    }
10304
10305    void skipCurrentReceiverLocked(ProcessRecord app) {
10306        for (BroadcastQueue queue : mBroadcastQueues) {
10307            queue.skipCurrentReceiverLocked(app);
10308        }
10309    }
10310
10311    /**
10312     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10313     * The application process will exit immediately after this call returns.
10314     * @param app object of the crashing app, null for the system server
10315     * @param crashInfo describing the exception
10316     */
10317    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10318        ProcessRecord r = findAppProcess(app, "Crash");
10319        final String processName = app == null ? "system_server"
10320                : (r == null ? "unknown" : r.processName);
10321
10322        handleApplicationCrashInner("crash", r, processName, crashInfo);
10323    }
10324
10325    /* Native crash reporting uses this inner version because it needs to be somewhat
10326     * decoupled from the AM-managed cleanup lifecycle
10327     */
10328    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10329            ApplicationErrorReport.CrashInfo crashInfo) {
10330        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10331                UserHandle.getUserId(Binder.getCallingUid()), processName,
10332                r == null ? -1 : r.info.flags,
10333                crashInfo.exceptionClassName,
10334                crashInfo.exceptionMessage,
10335                crashInfo.throwFileName,
10336                crashInfo.throwLineNumber);
10337
10338        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10339
10340        crashApplication(r, crashInfo);
10341    }
10342
10343    public void handleApplicationStrictModeViolation(
10344            IBinder app,
10345            int violationMask,
10346            StrictMode.ViolationInfo info) {
10347        ProcessRecord r = findAppProcess(app, "StrictMode");
10348        if (r == null) {
10349            return;
10350        }
10351
10352        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10353            Integer stackFingerprint = info.hashCode();
10354            boolean logIt = true;
10355            synchronized (mAlreadyLoggedViolatedStacks) {
10356                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10357                    logIt = false;
10358                    // TODO: sub-sample into EventLog for these, with
10359                    // the info.durationMillis?  Then we'd get
10360                    // the relative pain numbers, without logging all
10361                    // the stack traces repeatedly.  We'd want to do
10362                    // likewise in the client code, which also does
10363                    // dup suppression, before the Binder call.
10364                } else {
10365                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10366                        mAlreadyLoggedViolatedStacks.clear();
10367                    }
10368                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10369                }
10370            }
10371            if (logIt) {
10372                logStrictModeViolationToDropBox(r, info);
10373            }
10374        }
10375
10376        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10377            AppErrorResult result = new AppErrorResult();
10378            synchronized (this) {
10379                final long origId = Binder.clearCallingIdentity();
10380
10381                Message msg = Message.obtain();
10382                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10383                HashMap<String, Object> data = new HashMap<String, Object>();
10384                data.put("result", result);
10385                data.put("app", r);
10386                data.put("violationMask", violationMask);
10387                data.put("info", info);
10388                msg.obj = data;
10389                mHandler.sendMessage(msg);
10390
10391                Binder.restoreCallingIdentity(origId);
10392            }
10393            int res = result.get();
10394            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10395        }
10396    }
10397
10398    // Depending on the policy in effect, there could be a bunch of
10399    // these in quick succession so we try to batch these together to
10400    // minimize disk writes, number of dropbox entries, and maximize
10401    // compression, by having more fewer, larger records.
10402    private void logStrictModeViolationToDropBox(
10403            ProcessRecord process,
10404            StrictMode.ViolationInfo info) {
10405        if (info == null) {
10406            return;
10407        }
10408        final boolean isSystemApp = process == null ||
10409                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10410                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10411        final String processName = process == null ? "unknown" : process.processName;
10412        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10413        final DropBoxManager dbox = (DropBoxManager)
10414                mContext.getSystemService(Context.DROPBOX_SERVICE);
10415
10416        // Exit early if the dropbox isn't configured to accept this report type.
10417        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10418
10419        boolean bufferWasEmpty;
10420        boolean needsFlush;
10421        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10422        synchronized (sb) {
10423            bufferWasEmpty = sb.length() == 0;
10424            appendDropBoxProcessHeaders(process, processName, sb);
10425            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10426            sb.append("System-App: ").append(isSystemApp).append("\n");
10427            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10428            if (info.violationNumThisLoop != 0) {
10429                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10430            }
10431            if (info.numAnimationsRunning != 0) {
10432                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10433            }
10434            if (info.broadcastIntentAction != null) {
10435                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10436            }
10437            if (info.durationMillis != -1) {
10438                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10439            }
10440            if (info.numInstances != -1) {
10441                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10442            }
10443            if (info.tags != null) {
10444                for (String tag : info.tags) {
10445                    sb.append("Span-Tag: ").append(tag).append("\n");
10446                }
10447            }
10448            sb.append("\n");
10449            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10450                sb.append(info.crashInfo.stackTrace);
10451            }
10452            sb.append("\n");
10453
10454            // Only buffer up to ~64k.  Various logging bits truncate
10455            // things at 128k.
10456            needsFlush = (sb.length() > 64 * 1024);
10457        }
10458
10459        // Flush immediately if the buffer's grown too large, or this
10460        // is a non-system app.  Non-system apps are isolated with a
10461        // different tag & policy and not batched.
10462        //
10463        // Batching is useful during internal testing with
10464        // StrictMode settings turned up high.  Without batching,
10465        // thousands of separate files could be created on boot.
10466        if (!isSystemApp || needsFlush) {
10467            new Thread("Error dump: " + dropboxTag) {
10468                @Override
10469                public void run() {
10470                    String report;
10471                    synchronized (sb) {
10472                        report = sb.toString();
10473                        sb.delete(0, sb.length());
10474                        sb.trimToSize();
10475                    }
10476                    if (report.length() != 0) {
10477                        dbox.addText(dropboxTag, report);
10478                    }
10479                }
10480            }.start();
10481            return;
10482        }
10483
10484        // System app batching:
10485        if (!bufferWasEmpty) {
10486            // An existing dropbox-writing thread is outstanding, so
10487            // we don't need to start it up.  The existing thread will
10488            // catch the buffer appends we just did.
10489            return;
10490        }
10491
10492        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10493        // (After this point, we shouldn't access AMS internal data structures.)
10494        new Thread("Error dump: " + dropboxTag) {
10495            @Override
10496            public void run() {
10497                // 5 second sleep to let stacks arrive and be batched together
10498                try {
10499                    Thread.sleep(5000);  // 5 seconds
10500                } catch (InterruptedException e) {}
10501
10502                String errorReport;
10503                synchronized (mStrictModeBuffer) {
10504                    errorReport = mStrictModeBuffer.toString();
10505                    if (errorReport.length() == 0) {
10506                        return;
10507                    }
10508                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10509                    mStrictModeBuffer.trimToSize();
10510                }
10511                dbox.addText(dropboxTag, errorReport);
10512            }
10513        }.start();
10514    }
10515
10516    /**
10517     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10518     * @param app object of the crashing app, null for the system server
10519     * @param tag reported by the caller
10520     * @param crashInfo describing the context of the error
10521     * @return true if the process should exit immediately (WTF is fatal)
10522     */
10523    public boolean handleApplicationWtf(IBinder app, String tag,
10524            ApplicationErrorReport.CrashInfo crashInfo) {
10525        ProcessRecord r = findAppProcess(app, "WTF");
10526        final String processName = app == null ? "system_server"
10527                : (r == null ? "unknown" : r.processName);
10528
10529        EventLog.writeEvent(EventLogTags.AM_WTF,
10530                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10531                processName,
10532                r == null ? -1 : r.info.flags,
10533                tag, crashInfo.exceptionMessage);
10534
10535        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10536
10537        if (r != null && r.pid != Process.myPid() &&
10538                Settings.Global.getInt(mContext.getContentResolver(),
10539                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10540            crashApplication(r, crashInfo);
10541            return true;
10542        } else {
10543            return false;
10544        }
10545    }
10546
10547    /**
10548     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10549     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10550     */
10551    private ProcessRecord findAppProcess(IBinder app, String reason) {
10552        if (app == null) {
10553            return null;
10554        }
10555
10556        synchronized (this) {
10557            final int NP = mProcessNames.getMap().size();
10558            for (int ip=0; ip<NP; ip++) {
10559                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10560                final int NA = apps.size();
10561                for (int ia=0; ia<NA; ia++) {
10562                    ProcessRecord p = apps.valueAt(ia);
10563                    if (p.thread != null && p.thread.asBinder() == app) {
10564                        return p;
10565                    }
10566                }
10567            }
10568
10569            Slog.w(TAG, "Can't find mystery application for " + reason
10570                    + " from pid=" + Binder.getCallingPid()
10571                    + " uid=" + Binder.getCallingUid() + ": " + app);
10572            return null;
10573        }
10574    }
10575
10576    /**
10577     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10578     * to append various headers to the dropbox log text.
10579     */
10580    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10581            StringBuilder sb) {
10582        // Watchdog thread ends up invoking this function (with
10583        // a null ProcessRecord) to add the stack file to dropbox.
10584        // Do not acquire a lock on this (am) in such cases, as it
10585        // could cause a potential deadlock, if and when watchdog
10586        // is invoked due to unavailability of lock on am and it
10587        // would prevent watchdog from killing system_server.
10588        if (process == null) {
10589            sb.append("Process: ").append(processName).append("\n");
10590            return;
10591        }
10592        // Note: ProcessRecord 'process' is guarded by the service
10593        // instance.  (notably process.pkgList, which could otherwise change
10594        // concurrently during execution of this method)
10595        synchronized (this) {
10596            sb.append("Process: ").append(processName).append("\n");
10597            int flags = process.info.flags;
10598            IPackageManager pm = AppGlobals.getPackageManager();
10599            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10600            for (int ip=0; ip<process.pkgList.size(); ip++) {
10601                String pkg = process.pkgList.keyAt(ip);
10602                sb.append("Package: ").append(pkg);
10603                try {
10604                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10605                    if (pi != null) {
10606                        sb.append(" v").append(pi.versionCode);
10607                        if (pi.versionName != null) {
10608                            sb.append(" (").append(pi.versionName).append(")");
10609                        }
10610                    }
10611                } catch (RemoteException e) {
10612                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10613                }
10614                sb.append("\n");
10615            }
10616        }
10617    }
10618
10619    private static String processClass(ProcessRecord process) {
10620        if (process == null || process.pid == MY_PID) {
10621            return "system_server";
10622        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10623            return "system_app";
10624        } else {
10625            return "data_app";
10626        }
10627    }
10628
10629    /**
10630     * Write a description of an error (crash, WTF, ANR) to the drop box.
10631     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10632     * @param process which caused the error, null means the system server
10633     * @param activity which triggered the error, null if unknown
10634     * @param parent activity related to the error, null if unknown
10635     * @param subject line related to the error, null if absent
10636     * @param report in long form describing the error, null if absent
10637     * @param logFile to include in the report, null if none
10638     * @param crashInfo giving an application stack trace, null if absent
10639     */
10640    public void addErrorToDropBox(String eventType,
10641            ProcessRecord process, String processName, ActivityRecord activity,
10642            ActivityRecord parent, String subject,
10643            final String report, final File logFile,
10644            final ApplicationErrorReport.CrashInfo crashInfo) {
10645        // NOTE -- this must never acquire the ActivityManagerService lock,
10646        // otherwise the watchdog may be prevented from resetting the system.
10647
10648        final String dropboxTag = processClass(process) + "_" + eventType;
10649        final DropBoxManager dbox = (DropBoxManager)
10650                mContext.getSystemService(Context.DROPBOX_SERVICE);
10651
10652        // Exit early if the dropbox isn't configured to accept this report type.
10653        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10654
10655        final StringBuilder sb = new StringBuilder(1024);
10656        appendDropBoxProcessHeaders(process, processName, sb);
10657        if (activity != null) {
10658            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10659        }
10660        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10661            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10662        }
10663        if (parent != null && parent != activity) {
10664            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10665        }
10666        if (subject != null) {
10667            sb.append("Subject: ").append(subject).append("\n");
10668        }
10669        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10670        if (Debug.isDebuggerConnected()) {
10671            sb.append("Debugger: Connected\n");
10672        }
10673        sb.append("\n");
10674
10675        // Do the rest in a worker thread to avoid blocking the caller on I/O
10676        // (After this point, we shouldn't access AMS internal data structures.)
10677        Thread worker = new Thread("Error dump: " + dropboxTag) {
10678            @Override
10679            public void run() {
10680                if (report != null) {
10681                    sb.append(report);
10682                }
10683                if (logFile != null) {
10684                    try {
10685                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10686                                    "\n\n[[TRUNCATED]]"));
10687                    } catch (IOException e) {
10688                        Slog.e(TAG, "Error reading " + logFile, e);
10689                    }
10690                }
10691                if (crashInfo != null && crashInfo.stackTrace != null) {
10692                    sb.append(crashInfo.stackTrace);
10693                }
10694
10695                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10696                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10697                if (lines > 0) {
10698                    sb.append("\n");
10699
10700                    // Merge several logcat streams, and take the last N lines
10701                    InputStreamReader input = null;
10702                    try {
10703                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10704                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10705                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10706
10707                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10708                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10709                        input = new InputStreamReader(logcat.getInputStream());
10710
10711                        int num;
10712                        char[] buf = new char[8192];
10713                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10714                    } catch (IOException e) {
10715                        Slog.e(TAG, "Error running logcat", e);
10716                    } finally {
10717                        if (input != null) try { input.close(); } catch (IOException e) {}
10718                    }
10719                }
10720
10721                dbox.addText(dropboxTag, sb.toString());
10722            }
10723        };
10724
10725        if (process == null) {
10726            // If process is null, we are being called from some internal code
10727            // and may be about to die -- run this synchronously.
10728            worker.run();
10729        } else {
10730            worker.start();
10731        }
10732    }
10733
10734    /**
10735     * Bring up the "unexpected error" dialog box for a crashing app.
10736     * Deal with edge cases (intercepts from instrumented applications,
10737     * ActivityController, error intent receivers, that sort of thing).
10738     * @param r the application crashing
10739     * @param crashInfo describing the failure
10740     */
10741    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10742        long timeMillis = System.currentTimeMillis();
10743        String shortMsg = crashInfo.exceptionClassName;
10744        String longMsg = crashInfo.exceptionMessage;
10745        String stackTrace = crashInfo.stackTrace;
10746        if (shortMsg != null && longMsg != null) {
10747            longMsg = shortMsg + ": " + longMsg;
10748        } else if (shortMsg != null) {
10749            longMsg = shortMsg;
10750        }
10751
10752        AppErrorResult result = new AppErrorResult();
10753        synchronized (this) {
10754            if (mController != null) {
10755                try {
10756                    String name = r != null ? r.processName : null;
10757                    int pid = r != null ? r.pid : Binder.getCallingPid();
10758                    if (!mController.appCrashed(name, pid,
10759                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10760                        Slog.w(TAG, "Force-killing crashed app " + name
10761                                + " at watcher's request");
10762                        Process.killProcess(pid);
10763                        return;
10764                    }
10765                } catch (RemoteException e) {
10766                    mController = null;
10767                    Watchdog.getInstance().setActivityController(null);
10768                }
10769            }
10770
10771            final long origId = Binder.clearCallingIdentity();
10772
10773            // If this process is running instrumentation, finish it.
10774            if (r != null && r.instrumentationClass != null) {
10775                Slog.w(TAG, "Error in app " + r.processName
10776                      + " running instrumentation " + r.instrumentationClass + ":");
10777                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10778                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10779                Bundle info = new Bundle();
10780                info.putString("shortMsg", shortMsg);
10781                info.putString("longMsg", longMsg);
10782                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10783                Binder.restoreCallingIdentity(origId);
10784                return;
10785            }
10786
10787            // If we can't identify the process or it's already exceeded its crash quota,
10788            // quit right away without showing a crash dialog.
10789            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10790                Binder.restoreCallingIdentity(origId);
10791                return;
10792            }
10793
10794            Message msg = Message.obtain();
10795            msg.what = SHOW_ERROR_MSG;
10796            HashMap data = new HashMap();
10797            data.put("result", result);
10798            data.put("app", r);
10799            msg.obj = data;
10800            mHandler.sendMessage(msg);
10801
10802            Binder.restoreCallingIdentity(origId);
10803        }
10804
10805        int res = result.get();
10806
10807        Intent appErrorIntent = null;
10808        synchronized (this) {
10809            if (r != null && !r.isolated) {
10810                // XXX Can't keep track of crash time for isolated processes,
10811                // since they don't have a persistent identity.
10812                mProcessCrashTimes.put(r.info.processName, r.uid,
10813                        SystemClock.uptimeMillis());
10814            }
10815            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10816                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10817            }
10818        }
10819
10820        if (appErrorIntent != null) {
10821            try {
10822                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10823            } catch (ActivityNotFoundException e) {
10824                Slog.w(TAG, "bug report receiver dissappeared", e);
10825            }
10826        }
10827    }
10828
10829    Intent createAppErrorIntentLocked(ProcessRecord r,
10830            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10831        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10832        if (report == null) {
10833            return null;
10834        }
10835        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10836        result.setComponent(r.errorReportReceiver);
10837        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10838        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10839        return result;
10840    }
10841
10842    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10843            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10844        if (r.errorReportReceiver == null) {
10845            return null;
10846        }
10847
10848        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10849            return null;
10850        }
10851
10852        ApplicationErrorReport report = new ApplicationErrorReport();
10853        report.packageName = r.info.packageName;
10854        report.installerPackageName = r.errorReportReceiver.getPackageName();
10855        report.processName = r.processName;
10856        report.time = timeMillis;
10857        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10858
10859        if (r.crashing || r.forceCrashReport) {
10860            report.type = ApplicationErrorReport.TYPE_CRASH;
10861            report.crashInfo = crashInfo;
10862        } else if (r.notResponding) {
10863            report.type = ApplicationErrorReport.TYPE_ANR;
10864            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10865
10866            report.anrInfo.activity = r.notRespondingReport.tag;
10867            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10868            report.anrInfo.info = r.notRespondingReport.longMsg;
10869        }
10870
10871        return report;
10872    }
10873
10874    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10875        enforceNotIsolatedCaller("getProcessesInErrorState");
10876        // assume our apps are happy - lazy create the list
10877        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10878
10879        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10880                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10881        int userId = UserHandle.getUserId(Binder.getCallingUid());
10882
10883        synchronized (this) {
10884
10885            // iterate across all processes
10886            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10887                ProcessRecord app = mLruProcesses.get(i);
10888                if (!allUsers && app.userId != userId) {
10889                    continue;
10890                }
10891                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10892                    // This one's in trouble, so we'll generate a report for it
10893                    // crashes are higher priority (in case there's a crash *and* an anr)
10894                    ActivityManager.ProcessErrorStateInfo report = null;
10895                    if (app.crashing) {
10896                        report = app.crashingReport;
10897                    } else if (app.notResponding) {
10898                        report = app.notRespondingReport;
10899                    }
10900
10901                    if (report != null) {
10902                        if (errList == null) {
10903                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10904                        }
10905                        errList.add(report);
10906                    } else {
10907                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10908                                " crashing = " + app.crashing +
10909                                " notResponding = " + app.notResponding);
10910                    }
10911                }
10912            }
10913        }
10914
10915        return errList;
10916    }
10917
10918    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10919        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10920            if (currApp != null) {
10921                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10922            }
10923            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10924        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10925            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10926        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10927            if (currApp != null) {
10928                currApp.lru = 0;
10929            }
10930            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10931        } else if (adj >= ProcessList.SERVICE_ADJ) {
10932            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10933        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10934            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10935        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10936            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10937        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10938            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10939        } else {
10940            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10941        }
10942    }
10943
10944    private void fillInProcMemInfo(ProcessRecord app,
10945            ActivityManager.RunningAppProcessInfo outInfo) {
10946        outInfo.pid = app.pid;
10947        outInfo.uid = app.info.uid;
10948        if (mHeavyWeightProcess == app) {
10949            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10950        }
10951        if (app.persistent) {
10952            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10953        }
10954        if (app.activities.size() > 0) {
10955            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10956        }
10957        outInfo.lastTrimLevel = app.trimMemoryLevel;
10958        int adj = app.curAdj;
10959        outInfo.importance = oomAdjToImportance(adj, outInfo);
10960        outInfo.importanceReasonCode = app.adjTypeCode;
10961        outInfo.processState = app.curProcState;
10962    }
10963
10964    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10965        enforceNotIsolatedCaller("getRunningAppProcesses");
10966        // Lazy instantiation of list
10967        List<ActivityManager.RunningAppProcessInfo> runList = null;
10968        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10969                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10970        int userId = UserHandle.getUserId(Binder.getCallingUid());
10971        synchronized (this) {
10972            // Iterate across all processes
10973            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10974                ProcessRecord app = mLruProcesses.get(i);
10975                if (!allUsers && app.userId != userId) {
10976                    continue;
10977                }
10978                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10979                    // Generate process state info for running application
10980                    ActivityManager.RunningAppProcessInfo currApp =
10981                        new ActivityManager.RunningAppProcessInfo(app.processName,
10982                                app.pid, app.getPackageList());
10983                    fillInProcMemInfo(app, currApp);
10984                    if (app.adjSource instanceof ProcessRecord) {
10985                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10986                        currApp.importanceReasonImportance = oomAdjToImportance(
10987                                app.adjSourceOom, null);
10988                    } else if (app.adjSource instanceof ActivityRecord) {
10989                        ActivityRecord r = (ActivityRecord)app.adjSource;
10990                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10991                    }
10992                    if (app.adjTarget instanceof ComponentName) {
10993                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10994                    }
10995                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10996                    //        + " lru=" + currApp.lru);
10997                    if (runList == null) {
10998                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10999                    }
11000                    runList.add(currApp);
11001                }
11002            }
11003        }
11004        return runList;
11005    }
11006
11007    public List<ApplicationInfo> getRunningExternalApplications() {
11008        enforceNotIsolatedCaller("getRunningExternalApplications");
11009        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11010        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11011        if (runningApps != null && runningApps.size() > 0) {
11012            Set<String> extList = new HashSet<String>();
11013            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11014                if (app.pkgList != null) {
11015                    for (String pkg : app.pkgList) {
11016                        extList.add(pkg);
11017                    }
11018                }
11019            }
11020            IPackageManager pm = AppGlobals.getPackageManager();
11021            for (String pkg : extList) {
11022                try {
11023                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11024                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11025                        retList.add(info);
11026                    }
11027                } catch (RemoteException e) {
11028                }
11029            }
11030        }
11031        return retList;
11032    }
11033
11034    @Override
11035    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11036        enforceNotIsolatedCaller("getMyMemoryState");
11037        synchronized (this) {
11038            ProcessRecord proc;
11039            synchronized (mPidsSelfLocked) {
11040                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11041            }
11042            fillInProcMemInfo(proc, outInfo);
11043        }
11044    }
11045
11046    @Override
11047    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11048        if (checkCallingPermission(android.Manifest.permission.DUMP)
11049                != PackageManager.PERMISSION_GRANTED) {
11050            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11051                    + Binder.getCallingPid()
11052                    + ", uid=" + Binder.getCallingUid()
11053                    + " without permission "
11054                    + android.Manifest.permission.DUMP);
11055            return;
11056        }
11057
11058        boolean dumpAll = false;
11059        boolean dumpClient = false;
11060        String dumpPackage = null;
11061
11062        int opti = 0;
11063        while (opti < args.length) {
11064            String opt = args[opti];
11065            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11066                break;
11067            }
11068            opti++;
11069            if ("-a".equals(opt)) {
11070                dumpAll = true;
11071            } else if ("-c".equals(opt)) {
11072                dumpClient = true;
11073            } else if ("-h".equals(opt)) {
11074                pw.println("Activity manager dump options:");
11075                pw.println("  [-a] [-c] [-h] [cmd] ...");
11076                pw.println("  cmd may be one of:");
11077                pw.println("    a[ctivities]: activity stack state");
11078                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11079                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11080                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11081                pw.println("    o[om]: out of memory management");
11082                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11083                pw.println("    provider [COMP_SPEC]: provider client-side state");
11084                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11085                pw.println("    service [COMP_SPEC]: service client-side state");
11086                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11087                pw.println("    all: dump all activities");
11088                pw.println("    top: dump the top activity");
11089                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11090                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11091                pw.println("    a partial substring in a component name, a");
11092                pw.println("    hex object identifier.");
11093                pw.println("  -a: include all available server state.");
11094                pw.println("  -c: include client state.");
11095                return;
11096            } else {
11097                pw.println("Unknown argument: " + opt + "; use -h for help");
11098            }
11099        }
11100
11101        long origId = Binder.clearCallingIdentity();
11102        boolean more = false;
11103        // Is the caller requesting to dump a particular piece of data?
11104        if (opti < args.length) {
11105            String cmd = args[opti];
11106            opti++;
11107            if ("activities".equals(cmd) || "a".equals(cmd)) {
11108                synchronized (this) {
11109                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11110                }
11111            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11112                String[] newArgs;
11113                String name;
11114                if (opti >= args.length) {
11115                    name = null;
11116                    newArgs = EMPTY_STRING_ARRAY;
11117                } else {
11118                    name = args[opti];
11119                    opti++;
11120                    newArgs = new String[args.length - opti];
11121                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11122                            args.length - opti);
11123                }
11124                synchronized (this) {
11125                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11126                }
11127            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11128                String[] newArgs;
11129                String name;
11130                if (opti >= args.length) {
11131                    name = null;
11132                    newArgs = EMPTY_STRING_ARRAY;
11133                } else {
11134                    name = args[opti];
11135                    opti++;
11136                    newArgs = new String[args.length - opti];
11137                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11138                            args.length - opti);
11139                }
11140                synchronized (this) {
11141                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11142                }
11143            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11144                String[] newArgs;
11145                String name;
11146                if (opti >= args.length) {
11147                    name = null;
11148                    newArgs = EMPTY_STRING_ARRAY;
11149                } else {
11150                    name = args[opti];
11151                    opti++;
11152                    newArgs = new String[args.length - opti];
11153                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11154                            args.length - opti);
11155                }
11156                synchronized (this) {
11157                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11158                }
11159            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11160                synchronized (this) {
11161                    dumpOomLocked(fd, pw, args, opti, true);
11162                }
11163            } else if ("provider".equals(cmd)) {
11164                String[] newArgs;
11165                String name;
11166                if (opti >= args.length) {
11167                    name = null;
11168                    newArgs = EMPTY_STRING_ARRAY;
11169                } else {
11170                    name = args[opti];
11171                    opti++;
11172                    newArgs = new String[args.length - opti];
11173                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11174                }
11175                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11176                    pw.println("No providers match: " + name);
11177                    pw.println("Use -h for help.");
11178                }
11179            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11180                synchronized (this) {
11181                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11182                }
11183            } else if ("service".equals(cmd)) {
11184                String[] newArgs;
11185                String name;
11186                if (opti >= args.length) {
11187                    name = null;
11188                    newArgs = EMPTY_STRING_ARRAY;
11189                } else {
11190                    name = args[opti];
11191                    opti++;
11192                    newArgs = new String[args.length - opti];
11193                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11194                            args.length - opti);
11195                }
11196                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11197                    pw.println("No services match: " + name);
11198                    pw.println("Use -h for help.");
11199                }
11200            } else if ("package".equals(cmd)) {
11201                String[] newArgs;
11202                if (opti >= args.length) {
11203                    pw.println("package: no package name specified");
11204                    pw.println("Use -h for help.");
11205                } else {
11206                    dumpPackage = args[opti];
11207                    opti++;
11208                    newArgs = new String[args.length - opti];
11209                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11210                            args.length - opti);
11211                    args = newArgs;
11212                    opti = 0;
11213                    more = true;
11214                }
11215            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11216                synchronized (this) {
11217                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11218                }
11219            } else {
11220                // Dumping a single activity?
11221                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11222                    pw.println("Bad activity command, or no activities match: " + cmd);
11223                    pw.println("Use -h for help.");
11224                }
11225            }
11226            if (!more) {
11227                Binder.restoreCallingIdentity(origId);
11228                return;
11229            }
11230        }
11231
11232        // No piece of data specified, dump everything.
11233        synchronized (this) {
11234            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11235            pw.println();
11236            if (dumpAll) {
11237                pw.println("-------------------------------------------------------------------------------");
11238            }
11239            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11240            pw.println();
11241            if (dumpAll) {
11242                pw.println("-------------------------------------------------------------------------------");
11243            }
11244            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11245            pw.println();
11246            if (dumpAll) {
11247                pw.println("-------------------------------------------------------------------------------");
11248            }
11249            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11250            pw.println();
11251            if (dumpAll) {
11252                pw.println("-------------------------------------------------------------------------------");
11253            }
11254            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11255            pw.println();
11256            if (dumpAll) {
11257                pw.println("-------------------------------------------------------------------------------");
11258            }
11259            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11260        }
11261        Binder.restoreCallingIdentity(origId);
11262    }
11263
11264    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11265            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11266        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11267
11268        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11269                dumpPackage);
11270        boolean needSep = printedAnything;
11271
11272        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11273                dumpPackage, needSep, "  mFocusedActivity: ");
11274        if (printed) {
11275            printedAnything = true;
11276            needSep = false;
11277        }
11278
11279        if (dumpPackage == null) {
11280            if (needSep) {
11281                pw.println();
11282            }
11283            needSep = true;
11284            printedAnything = true;
11285            mStackSupervisor.dump(pw, "  ");
11286        }
11287
11288        if (mRecentTasks.size() > 0) {
11289            boolean printedHeader = false;
11290
11291            final int N = mRecentTasks.size();
11292            for (int i=0; i<N; i++) {
11293                TaskRecord tr = mRecentTasks.get(i);
11294                if (dumpPackage != null) {
11295                    if (tr.realActivity == null ||
11296                            !dumpPackage.equals(tr.realActivity)) {
11297                        continue;
11298                    }
11299                }
11300                if (!printedHeader) {
11301                    if (needSep) {
11302                        pw.println();
11303                    }
11304                    pw.println("  Recent tasks:");
11305                    printedHeader = true;
11306                    printedAnything = true;
11307                }
11308                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11309                        pw.println(tr);
11310                if (dumpAll) {
11311                    mRecentTasks.get(i).dump(pw, "    ");
11312                }
11313            }
11314        }
11315
11316        if (!printedAnything) {
11317            pw.println("  (nothing)");
11318        }
11319    }
11320
11321    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11322            int opti, boolean dumpAll, String dumpPackage) {
11323        boolean needSep = false;
11324        boolean printedAnything = false;
11325        int numPers = 0;
11326
11327        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11328
11329        if (dumpAll) {
11330            final int NP = mProcessNames.getMap().size();
11331            for (int ip=0; ip<NP; ip++) {
11332                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11333                final int NA = procs.size();
11334                for (int ia=0; ia<NA; ia++) {
11335                    ProcessRecord r = procs.valueAt(ia);
11336                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11337                        continue;
11338                    }
11339                    if (!needSep) {
11340                        pw.println("  All known processes:");
11341                        needSep = true;
11342                        printedAnything = true;
11343                    }
11344                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11345                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11346                        pw.print(" "); pw.println(r);
11347                    r.dump(pw, "    ");
11348                    if (r.persistent) {
11349                        numPers++;
11350                    }
11351                }
11352            }
11353        }
11354
11355        if (mIsolatedProcesses.size() > 0) {
11356            boolean printed = false;
11357            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11358                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11359                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11360                    continue;
11361                }
11362                if (!printed) {
11363                    if (needSep) {
11364                        pw.println();
11365                    }
11366                    pw.println("  Isolated process list (sorted by uid):");
11367                    printedAnything = true;
11368                    printed = true;
11369                    needSep = true;
11370                }
11371                pw.println(String.format("%sIsolated #%2d: %s",
11372                        "    ", i, r.toString()));
11373            }
11374        }
11375
11376        if (mLruProcesses.size() > 0) {
11377            if (needSep) {
11378                pw.println();
11379            }
11380            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11381                    pw.print(" total, non-act at ");
11382                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11383                    pw.print(", non-svc at ");
11384                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11385                    pw.println("):");
11386            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11387            needSep = true;
11388            printedAnything = true;
11389        }
11390
11391        if (dumpAll || dumpPackage != null) {
11392            synchronized (mPidsSelfLocked) {
11393                boolean printed = false;
11394                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11395                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11396                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11397                        continue;
11398                    }
11399                    if (!printed) {
11400                        if (needSep) pw.println();
11401                        needSep = true;
11402                        pw.println("  PID mappings:");
11403                        printed = true;
11404                        printedAnything = true;
11405                    }
11406                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11407                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11408                }
11409            }
11410        }
11411
11412        if (mForegroundProcesses.size() > 0) {
11413            synchronized (mPidsSelfLocked) {
11414                boolean printed = false;
11415                for (int i=0; i<mForegroundProcesses.size(); i++) {
11416                    ProcessRecord r = mPidsSelfLocked.get(
11417                            mForegroundProcesses.valueAt(i).pid);
11418                    if (dumpPackage != null && (r == null
11419                            || !r.pkgList.containsKey(dumpPackage))) {
11420                        continue;
11421                    }
11422                    if (!printed) {
11423                        if (needSep) pw.println();
11424                        needSep = true;
11425                        pw.println("  Foreground Processes:");
11426                        printed = true;
11427                        printedAnything = true;
11428                    }
11429                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11430                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11431                }
11432            }
11433        }
11434
11435        if (mPersistentStartingProcesses.size() > 0) {
11436            if (needSep) pw.println();
11437            needSep = true;
11438            printedAnything = true;
11439            pw.println("  Persisent processes that are starting:");
11440            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11441                    "Starting Norm", "Restarting PERS", dumpPackage);
11442        }
11443
11444        if (mRemovedProcesses.size() > 0) {
11445            if (needSep) pw.println();
11446            needSep = true;
11447            printedAnything = true;
11448            pw.println("  Processes that are being removed:");
11449            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11450                    "Removed Norm", "Removed PERS", dumpPackage);
11451        }
11452
11453        if (mProcessesOnHold.size() > 0) {
11454            if (needSep) pw.println();
11455            needSep = true;
11456            printedAnything = true;
11457            pw.println("  Processes that are on old until the system is ready:");
11458            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11459                    "OnHold Norm", "OnHold PERS", dumpPackage);
11460        }
11461
11462        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11463
11464        if (mProcessCrashTimes.getMap().size() > 0) {
11465            boolean printed = false;
11466            long now = SystemClock.uptimeMillis();
11467            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11468            final int NP = pmap.size();
11469            for (int ip=0; ip<NP; ip++) {
11470                String pname = pmap.keyAt(ip);
11471                SparseArray<Long> uids = pmap.valueAt(ip);
11472                final int N = uids.size();
11473                for (int i=0; i<N; i++) {
11474                    int puid = uids.keyAt(i);
11475                    ProcessRecord r = mProcessNames.get(pname, puid);
11476                    if (dumpPackage != null && (r == null
11477                            || !r.pkgList.containsKey(dumpPackage))) {
11478                        continue;
11479                    }
11480                    if (!printed) {
11481                        if (needSep) pw.println();
11482                        needSep = true;
11483                        pw.println("  Time since processes crashed:");
11484                        printed = true;
11485                        printedAnything = true;
11486                    }
11487                    pw.print("    Process "); pw.print(pname);
11488                            pw.print(" uid "); pw.print(puid);
11489                            pw.print(": last crashed ");
11490                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11491                            pw.println(" ago");
11492                }
11493            }
11494        }
11495
11496        if (mBadProcesses.getMap().size() > 0) {
11497            boolean printed = false;
11498            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11499            final int NP = pmap.size();
11500            for (int ip=0; ip<NP; ip++) {
11501                String pname = pmap.keyAt(ip);
11502                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11503                final int N = uids.size();
11504                for (int i=0; i<N; i++) {
11505                    int puid = uids.keyAt(i);
11506                    ProcessRecord r = mProcessNames.get(pname, puid);
11507                    if (dumpPackage != null && (r == null
11508                            || !r.pkgList.containsKey(dumpPackage))) {
11509                        continue;
11510                    }
11511                    if (!printed) {
11512                        if (needSep) pw.println();
11513                        needSep = true;
11514                        pw.println("  Bad processes:");
11515                        printedAnything = true;
11516                    }
11517                    BadProcessInfo info = uids.valueAt(i);
11518                    pw.print("    Bad process "); pw.print(pname);
11519                            pw.print(" uid "); pw.print(puid);
11520                            pw.print(": crashed at time "); pw.println(info.time);
11521                    if (info.shortMsg != null) {
11522                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11523                    }
11524                    if (info.longMsg != null) {
11525                        pw.print("      Long msg: "); pw.println(info.longMsg);
11526                    }
11527                    if (info.stack != null) {
11528                        pw.println("      Stack:");
11529                        int lastPos = 0;
11530                        for (int pos=0; pos<info.stack.length(); pos++) {
11531                            if (info.stack.charAt(pos) == '\n') {
11532                                pw.print("        ");
11533                                pw.write(info.stack, lastPos, pos-lastPos);
11534                                pw.println();
11535                                lastPos = pos+1;
11536                            }
11537                        }
11538                        if (lastPos < info.stack.length()) {
11539                            pw.print("        ");
11540                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11541                            pw.println();
11542                        }
11543                    }
11544                }
11545            }
11546        }
11547
11548        if (dumpPackage == null) {
11549            pw.println();
11550            needSep = false;
11551            pw.println("  mStartedUsers:");
11552            for (int i=0; i<mStartedUsers.size(); i++) {
11553                UserStartedState uss = mStartedUsers.valueAt(i);
11554                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11555                        pw.print(": "); uss.dump("", pw);
11556            }
11557            pw.print("  mStartedUserArray: [");
11558            for (int i=0; i<mStartedUserArray.length; i++) {
11559                if (i > 0) pw.print(", ");
11560                pw.print(mStartedUserArray[i]);
11561            }
11562            pw.println("]");
11563            pw.print("  mUserLru: [");
11564            for (int i=0; i<mUserLru.size(); i++) {
11565                if (i > 0) pw.print(", ");
11566                pw.print(mUserLru.get(i));
11567            }
11568            pw.println("]");
11569            if (dumpAll) {
11570                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11571            }
11572        }
11573        if (mHomeProcess != null && (dumpPackage == null
11574                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11575            if (needSep) {
11576                pw.println();
11577                needSep = false;
11578            }
11579            pw.println("  mHomeProcess: " + mHomeProcess);
11580        }
11581        if (mPreviousProcess != null && (dumpPackage == null
11582                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11583            if (needSep) {
11584                pw.println();
11585                needSep = false;
11586            }
11587            pw.println("  mPreviousProcess: " + mPreviousProcess);
11588        }
11589        if (dumpAll) {
11590            StringBuilder sb = new StringBuilder(128);
11591            sb.append("  mPreviousProcessVisibleTime: ");
11592            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11593            pw.println(sb);
11594        }
11595        if (mHeavyWeightProcess != null && (dumpPackage == null
11596                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11597            if (needSep) {
11598                pw.println();
11599                needSep = false;
11600            }
11601            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11602        }
11603        if (dumpPackage == null) {
11604            pw.println("  mConfiguration: " + mConfiguration);
11605        }
11606        if (dumpAll) {
11607            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11608            if (mCompatModePackages.getPackages().size() > 0) {
11609                boolean printed = false;
11610                for (Map.Entry<String, Integer> entry
11611                        : mCompatModePackages.getPackages().entrySet()) {
11612                    String pkg = entry.getKey();
11613                    int mode = entry.getValue();
11614                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11615                        continue;
11616                    }
11617                    if (!printed) {
11618                        pw.println("  mScreenCompatPackages:");
11619                        printed = true;
11620                    }
11621                    pw.print("    "); pw.print(pkg); pw.print(": ");
11622                            pw.print(mode); pw.println();
11623                }
11624            }
11625        }
11626        if (dumpPackage == null) {
11627            if (mSleeping || mWentToSleep || mLockScreenShown) {
11628                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11629                        + " mLockScreenShown " + mLockScreenShown);
11630            }
11631            if (mShuttingDown || mRunningVoice) {
11632                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11633            }
11634        }
11635        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11636                || mOrigWaitForDebugger) {
11637            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11638                    || dumpPackage.equals(mOrigDebugApp)) {
11639                if (needSep) {
11640                    pw.println();
11641                    needSep = false;
11642                }
11643                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11644                        + " mDebugTransient=" + mDebugTransient
11645                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11646            }
11647        }
11648        if (mOpenGlTraceApp != null) {
11649            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11650                if (needSep) {
11651                    pw.println();
11652                    needSep = false;
11653                }
11654                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11655            }
11656        }
11657        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11658                || mProfileFd != null) {
11659            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11660                if (needSep) {
11661                    pw.println();
11662                    needSep = false;
11663                }
11664                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11665                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11666                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11667                        + mAutoStopProfiler);
11668            }
11669        }
11670        if (dumpPackage == null) {
11671            if (mAlwaysFinishActivities || mController != null) {
11672                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11673                        + " mController=" + mController);
11674            }
11675            if (dumpAll) {
11676                pw.println("  Total persistent processes: " + numPers);
11677                pw.println("  mProcessesReady=" + mProcessesReady
11678                        + " mSystemReady=" + mSystemReady);
11679                pw.println("  mBooting=" + mBooting
11680                        + " mBooted=" + mBooted
11681                        + " mFactoryTest=" + mFactoryTest);
11682                pw.print("  mLastPowerCheckRealtime=");
11683                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11684                        pw.println("");
11685                pw.print("  mLastPowerCheckUptime=");
11686                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11687                        pw.println("");
11688                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11689                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11690                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11691                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11692                        + " (" + mLruProcesses.size() + " total)"
11693                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11694                        + " mNumServiceProcs=" + mNumServiceProcs
11695                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11696                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11697                        + " mLastMemoryLevel" + mLastMemoryLevel
11698                        + " mLastNumProcesses" + mLastNumProcesses);
11699                long now = SystemClock.uptimeMillis();
11700                pw.print("  mLastIdleTime=");
11701                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11702                        pw.print(" mLowRamSinceLastIdle=");
11703                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11704                        pw.println();
11705            }
11706        }
11707
11708        if (!printedAnything) {
11709            pw.println("  (nothing)");
11710        }
11711    }
11712
11713    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11714            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11715        if (mProcessesToGc.size() > 0) {
11716            boolean printed = false;
11717            long now = SystemClock.uptimeMillis();
11718            for (int i=0; i<mProcessesToGc.size(); i++) {
11719                ProcessRecord proc = mProcessesToGc.get(i);
11720                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11721                    continue;
11722                }
11723                if (!printed) {
11724                    if (needSep) pw.println();
11725                    needSep = true;
11726                    pw.println("  Processes that are waiting to GC:");
11727                    printed = true;
11728                }
11729                pw.print("    Process "); pw.println(proc);
11730                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11731                        pw.print(", last gced=");
11732                        pw.print(now-proc.lastRequestedGc);
11733                        pw.print(" ms ago, last lowMem=");
11734                        pw.print(now-proc.lastLowMemory);
11735                        pw.println(" ms ago");
11736
11737            }
11738        }
11739        return needSep;
11740    }
11741
11742    void printOomLevel(PrintWriter pw, String name, int adj) {
11743        pw.print("    ");
11744        if (adj >= 0) {
11745            pw.print(' ');
11746            if (adj < 10) pw.print(' ');
11747        } else {
11748            if (adj > -10) pw.print(' ');
11749        }
11750        pw.print(adj);
11751        pw.print(": ");
11752        pw.print(name);
11753        pw.print(" (");
11754        pw.print(mProcessList.getMemLevel(adj)/1024);
11755        pw.println(" kB)");
11756    }
11757
11758    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11759            int opti, boolean dumpAll) {
11760        boolean needSep = false;
11761
11762        if (mLruProcesses.size() > 0) {
11763            if (needSep) pw.println();
11764            needSep = true;
11765            pw.println("  OOM levels:");
11766            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11767            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11768            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11769            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11770            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11771            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11772            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11773            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11774            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11775            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11776            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11777            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11778            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11779
11780            if (needSep) pw.println();
11781            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11782                    pw.print(" total, non-act at ");
11783                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11784                    pw.print(", non-svc at ");
11785                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11786                    pw.println("):");
11787            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11788            needSep = true;
11789        }
11790
11791        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11792
11793        pw.println();
11794        pw.println("  mHomeProcess: " + mHomeProcess);
11795        pw.println("  mPreviousProcess: " + mPreviousProcess);
11796        if (mHeavyWeightProcess != null) {
11797            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11798        }
11799
11800        return true;
11801    }
11802
11803    /**
11804     * There are three ways to call this:
11805     *  - no provider specified: dump all the providers
11806     *  - a flattened component name that matched an existing provider was specified as the
11807     *    first arg: dump that one provider
11808     *  - the first arg isn't the flattened component name of an existing provider:
11809     *    dump all providers whose component contains the first arg as a substring
11810     */
11811    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11812            int opti, boolean dumpAll) {
11813        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11814    }
11815
11816    static class ItemMatcher {
11817        ArrayList<ComponentName> components;
11818        ArrayList<String> strings;
11819        ArrayList<Integer> objects;
11820        boolean all;
11821
11822        ItemMatcher() {
11823            all = true;
11824        }
11825
11826        void build(String name) {
11827            ComponentName componentName = ComponentName.unflattenFromString(name);
11828            if (componentName != null) {
11829                if (components == null) {
11830                    components = new ArrayList<ComponentName>();
11831                }
11832                components.add(componentName);
11833                all = false;
11834            } else {
11835                int objectId = 0;
11836                // Not a '/' separated full component name; maybe an object ID?
11837                try {
11838                    objectId = Integer.parseInt(name, 16);
11839                    if (objects == null) {
11840                        objects = new ArrayList<Integer>();
11841                    }
11842                    objects.add(objectId);
11843                    all = false;
11844                } catch (RuntimeException e) {
11845                    // Not an integer; just do string match.
11846                    if (strings == null) {
11847                        strings = new ArrayList<String>();
11848                    }
11849                    strings.add(name);
11850                    all = false;
11851                }
11852            }
11853        }
11854
11855        int build(String[] args, int opti) {
11856            for (; opti<args.length; opti++) {
11857                String name = args[opti];
11858                if ("--".equals(name)) {
11859                    return opti+1;
11860                }
11861                build(name);
11862            }
11863            return opti;
11864        }
11865
11866        boolean match(Object object, ComponentName comp) {
11867            if (all) {
11868                return true;
11869            }
11870            if (components != null) {
11871                for (int i=0; i<components.size(); i++) {
11872                    if (components.get(i).equals(comp)) {
11873                        return true;
11874                    }
11875                }
11876            }
11877            if (objects != null) {
11878                for (int i=0; i<objects.size(); i++) {
11879                    if (System.identityHashCode(object) == objects.get(i)) {
11880                        return true;
11881                    }
11882                }
11883            }
11884            if (strings != null) {
11885                String flat = comp.flattenToString();
11886                for (int i=0; i<strings.size(); i++) {
11887                    if (flat.contains(strings.get(i))) {
11888                        return true;
11889                    }
11890                }
11891            }
11892            return false;
11893        }
11894    }
11895
11896    /**
11897     * There are three things that cmd can be:
11898     *  - a flattened component name that matches an existing activity
11899     *  - the cmd arg isn't the flattened component name of an existing activity:
11900     *    dump all activity whose component contains the cmd as a substring
11901     *  - A hex number of the ActivityRecord object instance.
11902     */
11903    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11904            int opti, boolean dumpAll) {
11905        ArrayList<ActivityRecord> activities;
11906
11907        synchronized (this) {
11908            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11909        }
11910
11911        if (activities.size() <= 0) {
11912            return false;
11913        }
11914
11915        String[] newArgs = new String[args.length - opti];
11916        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11917
11918        TaskRecord lastTask = null;
11919        boolean needSep = false;
11920        for (int i=activities.size()-1; i>=0; i--) {
11921            ActivityRecord r = activities.get(i);
11922            if (needSep) {
11923                pw.println();
11924            }
11925            needSep = true;
11926            synchronized (this) {
11927                if (lastTask != r.task) {
11928                    lastTask = r.task;
11929                    pw.print("TASK "); pw.print(lastTask.affinity);
11930                            pw.print(" id="); pw.println(lastTask.taskId);
11931                    if (dumpAll) {
11932                        lastTask.dump(pw, "  ");
11933                    }
11934                }
11935            }
11936            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11937        }
11938        return true;
11939    }
11940
11941    /**
11942     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11943     * there is a thread associated with the activity.
11944     */
11945    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11946            final ActivityRecord r, String[] args, boolean dumpAll) {
11947        String innerPrefix = prefix + "  ";
11948        synchronized (this) {
11949            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11950                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11951                    pw.print(" pid=");
11952                    if (r.app != null) pw.println(r.app.pid);
11953                    else pw.println("(not running)");
11954            if (dumpAll) {
11955                r.dump(pw, innerPrefix);
11956            }
11957        }
11958        if (r.app != null && r.app.thread != null) {
11959            // flush anything that is already in the PrintWriter since the thread is going
11960            // to write to the file descriptor directly
11961            pw.flush();
11962            try {
11963                TransferPipe tp = new TransferPipe();
11964                try {
11965                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11966                            r.appToken, innerPrefix, args);
11967                    tp.go(fd);
11968                } finally {
11969                    tp.kill();
11970                }
11971            } catch (IOException e) {
11972                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11973            } catch (RemoteException e) {
11974                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11975            }
11976        }
11977    }
11978
11979    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11980            int opti, boolean dumpAll, String dumpPackage) {
11981        boolean needSep = false;
11982        boolean onlyHistory = false;
11983        boolean printedAnything = false;
11984
11985        if ("history".equals(dumpPackage)) {
11986            if (opti < args.length && "-s".equals(args[opti])) {
11987                dumpAll = false;
11988            }
11989            onlyHistory = true;
11990            dumpPackage = null;
11991        }
11992
11993        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11994        if (!onlyHistory && dumpAll) {
11995            if (mRegisteredReceivers.size() > 0) {
11996                boolean printed = false;
11997                Iterator it = mRegisteredReceivers.values().iterator();
11998                while (it.hasNext()) {
11999                    ReceiverList r = (ReceiverList)it.next();
12000                    if (dumpPackage != null && (r.app == null ||
12001                            !dumpPackage.equals(r.app.info.packageName))) {
12002                        continue;
12003                    }
12004                    if (!printed) {
12005                        pw.println("  Registered Receivers:");
12006                        needSep = true;
12007                        printed = true;
12008                        printedAnything = true;
12009                    }
12010                    pw.print("  * "); pw.println(r);
12011                    r.dump(pw, "    ");
12012                }
12013            }
12014
12015            if (mReceiverResolver.dump(pw, needSep ?
12016                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12017                    "    ", dumpPackage, false)) {
12018                needSep = true;
12019                printedAnything = true;
12020            }
12021        }
12022
12023        for (BroadcastQueue q : mBroadcastQueues) {
12024            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12025            printedAnything |= needSep;
12026        }
12027
12028        needSep = true;
12029
12030        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12031            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12032                if (needSep) {
12033                    pw.println();
12034                }
12035                needSep = true;
12036                printedAnything = true;
12037                pw.print("  Sticky broadcasts for user ");
12038                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12039                StringBuilder sb = new StringBuilder(128);
12040                for (Map.Entry<String, ArrayList<Intent>> ent
12041                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12042                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12043                    if (dumpAll) {
12044                        pw.println(":");
12045                        ArrayList<Intent> intents = ent.getValue();
12046                        final int N = intents.size();
12047                        for (int i=0; i<N; i++) {
12048                            sb.setLength(0);
12049                            sb.append("    Intent: ");
12050                            intents.get(i).toShortString(sb, false, true, false, false);
12051                            pw.println(sb.toString());
12052                            Bundle bundle = intents.get(i).getExtras();
12053                            if (bundle != null) {
12054                                pw.print("      ");
12055                                pw.println(bundle.toString());
12056                            }
12057                        }
12058                    } else {
12059                        pw.println("");
12060                    }
12061                }
12062            }
12063        }
12064
12065        if (!onlyHistory && dumpAll) {
12066            pw.println();
12067            for (BroadcastQueue queue : mBroadcastQueues) {
12068                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12069                        + queue.mBroadcastsScheduled);
12070            }
12071            pw.println("  mHandler:");
12072            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12073            needSep = true;
12074            printedAnything = true;
12075        }
12076
12077        if (!printedAnything) {
12078            pw.println("  (nothing)");
12079        }
12080    }
12081
12082    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12083            int opti, boolean dumpAll, String dumpPackage) {
12084        boolean needSep;
12085        boolean printedAnything = false;
12086
12087        ItemMatcher matcher = new ItemMatcher();
12088        matcher.build(args, opti);
12089
12090        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12091
12092        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12093        printedAnything |= needSep;
12094
12095        if (mLaunchingProviders.size() > 0) {
12096            boolean printed = false;
12097            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12098                ContentProviderRecord r = mLaunchingProviders.get(i);
12099                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12100                    continue;
12101                }
12102                if (!printed) {
12103                    if (needSep) pw.println();
12104                    needSep = true;
12105                    pw.println("  Launching content providers:");
12106                    printed = true;
12107                    printedAnything = true;
12108                }
12109                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12110                        pw.println(r);
12111            }
12112        }
12113
12114        if (mGrantedUriPermissions.size() > 0) {
12115            boolean printed = false;
12116            int dumpUid = -2;
12117            if (dumpPackage != null) {
12118                try {
12119                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12120                } catch (NameNotFoundException e) {
12121                    dumpUid = -1;
12122                }
12123            }
12124            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12125                int uid = mGrantedUriPermissions.keyAt(i);
12126                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12127                    continue;
12128                }
12129                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12130                if (!printed) {
12131                    if (needSep) pw.println();
12132                    needSep = true;
12133                    pw.println("  Granted Uri Permissions:");
12134                    printed = true;
12135                    printedAnything = true;
12136                }
12137                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12138                for (UriPermission perm : perms.values()) {
12139                    pw.print("    "); pw.println(perm);
12140                    if (dumpAll) {
12141                        perm.dump(pw, "      ");
12142                    }
12143                }
12144            }
12145        }
12146
12147        if (!printedAnything) {
12148            pw.println("  (nothing)");
12149        }
12150    }
12151
12152    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12153            int opti, boolean dumpAll, String dumpPackage) {
12154        boolean printed = false;
12155
12156        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12157
12158        if (mIntentSenderRecords.size() > 0) {
12159            Iterator<WeakReference<PendingIntentRecord>> it
12160                    = mIntentSenderRecords.values().iterator();
12161            while (it.hasNext()) {
12162                WeakReference<PendingIntentRecord> ref = it.next();
12163                PendingIntentRecord rec = ref != null ? ref.get(): null;
12164                if (dumpPackage != null && (rec == null
12165                        || !dumpPackage.equals(rec.key.packageName))) {
12166                    continue;
12167                }
12168                printed = true;
12169                if (rec != null) {
12170                    pw.print("  * "); pw.println(rec);
12171                    if (dumpAll) {
12172                        rec.dump(pw, "    ");
12173                    }
12174                } else {
12175                    pw.print("  * "); pw.println(ref);
12176                }
12177            }
12178        }
12179
12180        if (!printed) {
12181            pw.println("  (nothing)");
12182        }
12183    }
12184
12185    private static final int dumpProcessList(PrintWriter pw,
12186            ActivityManagerService service, List list,
12187            String prefix, String normalLabel, String persistentLabel,
12188            String dumpPackage) {
12189        int numPers = 0;
12190        final int N = list.size()-1;
12191        for (int i=N; i>=0; i--) {
12192            ProcessRecord r = (ProcessRecord)list.get(i);
12193            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12194                continue;
12195            }
12196            pw.println(String.format("%s%s #%2d: %s",
12197                    prefix, (r.persistent ? persistentLabel : normalLabel),
12198                    i, r.toString()));
12199            if (r.persistent) {
12200                numPers++;
12201            }
12202        }
12203        return numPers;
12204    }
12205
12206    private static final boolean dumpProcessOomList(PrintWriter pw,
12207            ActivityManagerService service, List<ProcessRecord> origList,
12208            String prefix, String normalLabel, String persistentLabel,
12209            boolean inclDetails, String dumpPackage) {
12210
12211        ArrayList<Pair<ProcessRecord, Integer>> list
12212                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12213        for (int i=0; i<origList.size(); i++) {
12214            ProcessRecord r = origList.get(i);
12215            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12216                continue;
12217            }
12218            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12219        }
12220
12221        if (list.size() <= 0) {
12222            return false;
12223        }
12224
12225        Comparator<Pair<ProcessRecord, Integer>> comparator
12226                = new Comparator<Pair<ProcessRecord, Integer>>() {
12227            @Override
12228            public int compare(Pair<ProcessRecord, Integer> object1,
12229                    Pair<ProcessRecord, Integer> object2) {
12230                if (object1.first.setAdj != object2.first.setAdj) {
12231                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12232                }
12233                if (object1.second.intValue() != object2.second.intValue()) {
12234                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12235                }
12236                return 0;
12237            }
12238        };
12239
12240        Collections.sort(list, comparator);
12241
12242        final long curRealtime = SystemClock.elapsedRealtime();
12243        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12244        final long curUptime = SystemClock.uptimeMillis();
12245        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12246
12247        for (int i=list.size()-1; i>=0; i--) {
12248            ProcessRecord r = list.get(i).first;
12249            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12250            char schedGroup;
12251            switch (r.setSchedGroup) {
12252                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12253                    schedGroup = 'B';
12254                    break;
12255                case Process.THREAD_GROUP_DEFAULT:
12256                    schedGroup = 'F';
12257                    break;
12258                default:
12259                    schedGroup = '?';
12260                    break;
12261            }
12262            char foreground;
12263            if (r.foregroundActivities) {
12264                foreground = 'A';
12265            } else if (r.foregroundServices) {
12266                foreground = 'S';
12267            } else {
12268                foreground = ' ';
12269            }
12270            String procState = ProcessList.makeProcStateString(r.curProcState);
12271            pw.print(prefix);
12272            pw.print(r.persistent ? persistentLabel : normalLabel);
12273            pw.print(" #");
12274            int num = (origList.size()-1)-list.get(i).second;
12275            if (num < 10) pw.print(' ');
12276            pw.print(num);
12277            pw.print(": ");
12278            pw.print(oomAdj);
12279            pw.print(' ');
12280            pw.print(schedGroup);
12281            pw.print('/');
12282            pw.print(foreground);
12283            pw.print('/');
12284            pw.print(procState);
12285            pw.print(" trm:");
12286            if (r.trimMemoryLevel < 10) pw.print(' ');
12287            pw.print(r.trimMemoryLevel);
12288            pw.print(' ');
12289            pw.print(r.toShortString());
12290            pw.print(" (");
12291            pw.print(r.adjType);
12292            pw.println(')');
12293            if (r.adjSource != null || r.adjTarget != null) {
12294                pw.print(prefix);
12295                pw.print("    ");
12296                if (r.adjTarget instanceof ComponentName) {
12297                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12298                } else if (r.adjTarget != null) {
12299                    pw.print(r.adjTarget.toString());
12300                } else {
12301                    pw.print("{null}");
12302                }
12303                pw.print("<=");
12304                if (r.adjSource instanceof ProcessRecord) {
12305                    pw.print("Proc{");
12306                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12307                    pw.println("}");
12308                } else if (r.adjSource != null) {
12309                    pw.println(r.adjSource.toString());
12310                } else {
12311                    pw.println("{null}");
12312                }
12313            }
12314            if (inclDetails) {
12315                pw.print(prefix);
12316                pw.print("    ");
12317                pw.print("oom: max="); pw.print(r.maxAdj);
12318                pw.print(" curRaw="); pw.print(r.curRawAdj);
12319                pw.print(" setRaw="); pw.print(r.setRawAdj);
12320                pw.print(" cur="); pw.print(r.curAdj);
12321                pw.print(" set="); pw.println(r.setAdj);
12322                pw.print(prefix);
12323                pw.print("    ");
12324                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12325                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12326                pw.print(" lastPss="); pw.print(r.lastPss);
12327                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12328                pw.print(prefix);
12329                pw.print("    ");
12330                pw.print("keeping="); pw.print(r.keeping);
12331                pw.print(" cached="); pw.print(r.cached);
12332                pw.print(" empty="); pw.print(r.empty);
12333                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12334
12335                if (!r.keeping) {
12336                    if (r.lastWakeTime != 0) {
12337                        long wtime;
12338                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12339                        synchronized (stats) {
12340                            wtime = stats.getProcessWakeTime(r.info.uid,
12341                                    r.pid, curRealtime);
12342                        }
12343                        long timeUsed = wtime - r.lastWakeTime;
12344                        pw.print(prefix);
12345                        pw.print("    ");
12346                        pw.print("keep awake over ");
12347                        TimeUtils.formatDuration(realtimeSince, pw);
12348                        pw.print(" used ");
12349                        TimeUtils.formatDuration(timeUsed, pw);
12350                        pw.print(" (");
12351                        pw.print((timeUsed*100)/realtimeSince);
12352                        pw.println("%)");
12353                    }
12354                    if (r.lastCpuTime != 0) {
12355                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12356                        pw.print(prefix);
12357                        pw.print("    ");
12358                        pw.print("run cpu over ");
12359                        TimeUtils.formatDuration(uptimeSince, pw);
12360                        pw.print(" used ");
12361                        TimeUtils.formatDuration(timeUsed, pw);
12362                        pw.print(" (");
12363                        pw.print((timeUsed*100)/uptimeSince);
12364                        pw.println("%)");
12365                    }
12366                }
12367            }
12368        }
12369        return true;
12370    }
12371
12372    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12373        ArrayList<ProcessRecord> procs;
12374        synchronized (this) {
12375            if (args != null && args.length > start
12376                    && args[start].charAt(0) != '-') {
12377                procs = new ArrayList<ProcessRecord>();
12378                int pid = -1;
12379                try {
12380                    pid = Integer.parseInt(args[start]);
12381                } catch (NumberFormatException e) {
12382                }
12383                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12384                    ProcessRecord proc = mLruProcesses.get(i);
12385                    if (proc.pid == pid) {
12386                        procs.add(proc);
12387                    } else if (proc.processName.equals(args[start])) {
12388                        procs.add(proc);
12389                    }
12390                }
12391                if (procs.size() <= 0) {
12392                    return null;
12393                }
12394            } else {
12395                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12396            }
12397        }
12398        return procs;
12399    }
12400
12401    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12402            PrintWriter pw, String[] args) {
12403        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12404        if (procs == null) {
12405            pw.println("No process found for: " + args[0]);
12406            return;
12407        }
12408
12409        long uptime = SystemClock.uptimeMillis();
12410        long realtime = SystemClock.elapsedRealtime();
12411        pw.println("Applications Graphics Acceleration Info:");
12412        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12413
12414        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12415            ProcessRecord r = procs.get(i);
12416            if (r.thread != null) {
12417                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12418                pw.flush();
12419                try {
12420                    TransferPipe tp = new TransferPipe();
12421                    try {
12422                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12423                        tp.go(fd);
12424                    } finally {
12425                        tp.kill();
12426                    }
12427                } catch (IOException e) {
12428                    pw.println("Failure while dumping the app: " + r);
12429                    pw.flush();
12430                } catch (RemoteException e) {
12431                    pw.println("Got a RemoteException while dumping the app " + r);
12432                    pw.flush();
12433                }
12434            }
12435        }
12436    }
12437
12438    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12439        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12440        if (procs == null) {
12441            pw.println("No process found for: " + args[0]);
12442            return;
12443        }
12444
12445        pw.println("Applications Database Info:");
12446
12447        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12448            ProcessRecord r = procs.get(i);
12449            if (r.thread != null) {
12450                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12451                pw.flush();
12452                try {
12453                    TransferPipe tp = new TransferPipe();
12454                    try {
12455                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12456                        tp.go(fd);
12457                    } finally {
12458                        tp.kill();
12459                    }
12460                } catch (IOException e) {
12461                    pw.println("Failure while dumping the app: " + r);
12462                    pw.flush();
12463                } catch (RemoteException e) {
12464                    pw.println("Got a RemoteException while dumping the app " + r);
12465                    pw.flush();
12466                }
12467            }
12468        }
12469    }
12470
12471    final static class MemItem {
12472        final boolean isProc;
12473        final String label;
12474        final String shortLabel;
12475        final long pss;
12476        final int id;
12477        final boolean hasActivities;
12478        ArrayList<MemItem> subitems;
12479
12480        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12481                boolean _hasActivities) {
12482            isProc = true;
12483            label = _label;
12484            shortLabel = _shortLabel;
12485            pss = _pss;
12486            id = _id;
12487            hasActivities = _hasActivities;
12488        }
12489
12490        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12491            isProc = false;
12492            label = _label;
12493            shortLabel = _shortLabel;
12494            pss = _pss;
12495            id = _id;
12496            hasActivities = false;
12497        }
12498    }
12499
12500    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12501            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12502        if (sort && !isCompact) {
12503            Collections.sort(items, new Comparator<MemItem>() {
12504                @Override
12505                public int compare(MemItem lhs, MemItem rhs) {
12506                    if (lhs.pss < rhs.pss) {
12507                        return 1;
12508                    } else if (lhs.pss > rhs.pss) {
12509                        return -1;
12510                    }
12511                    return 0;
12512                }
12513            });
12514        }
12515
12516        for (int i=0; i<items.size(); i++) {
12517            MemItem mi = items.get(i);
12518            if (!isCompact) {
12519                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12520            } else if (mi.isProc) {
12521                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12522                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12523                pw.println(mi.hasActivities ? ",a" : ",e");
12524            } else {
12525                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12526                pw.println(mi.pss);
12527            }
12528            if (mi.subitems != null) {
12529                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12530                        true, isCompact);
12531            }
12532        }
12533    }
12534
12535    // These are in KB.
12536    static final long[] DUMP_MEM_BUCKETS = new long[] {
12537        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12538        120*1024, 160*1024, 200*1024,
12539        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12540        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12541    };
12542
12543    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12544            boolean stackLike) {
12545        int start = label.lastIndexOf('.');
12546        if (start >= 0) start++;
12547        else start = 0;
12548        int end = label.length();
12549        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12550            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12551                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12552                out.append(bucket);
12553                out.append(stackLike ? "MB." : "MB ");
12554                out.append(label, start, end);
12555                return;
12556            }
12557        }
12558        out.append(memKB/1024);
12559        out.append(stackLike ? "MB." : "MB ");
12560        out.append(label, start, end);
12561    }
12562
12563    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12564            ProcessList.NATIVE_ADJ,
12565            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12566            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12567            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12568            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12569            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12570    };
12571    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12572            "Native",
12573            "System", "Persistent", "Foreground",
12574            "Visible", "Perceptible",
12575            "Heavy Weight", "Backup",
12576            "A Services", "Home",
12577            "Previous", "B Services", "Cached"
12578    };
12579    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12580            "native",
12581            "sys", "pers", "fore",
12582            "vis", "percept",
12583            "heavy", "backup",
12584            "servicea", "home",
12585            "prev", "serviceb", "cached"
12586    };
12587
12588    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12589            long realtime, boolean isCheckinRequest, boolean isCompact) {
12590        if (isCheckinRequest || isCompact) {
12591            // short checkin version
12592            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12593        } else {
12594            pw.println("Applications Memory Usage (kB):");
12595            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12596        }
12597    }
12598
12599    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12600            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12601        boolean dumpDetails = false;
12602        boolean dumpFullDetails = false;
12603        boolean dumpDalvik = false;
12604        boolean oomOnly = false;
12605        boolean isCompact = false;
12606        boolean localOnly = false;
12607
12608        int opti = 0;
12609        while (opti < args.length) {
12610            String opt = args[opti];
12611            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12612                break;
12613            }
12614            opti++;
12615            if ("-a".equals(opt)) {
12616                dumpDetails = true;
12617                dumpFullDetails = true;
12618                dumpDalvik = true;
12619            } else if ("-d".equals(opt)) {
12620                dumpDalvik = true;
12621            } else if ("-c".equals(opt)) {
12622                isCompact = true;
12623            } else if ("--oom".equals(opt)) {
12624                oomOnly = true;
12625            } else if ("--local".equals(opt)) {
12626                localOnly = true;
12627            } else if ("-h".equals(opt)) {
12628                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12629                pw.println("  -a: include all available information for each process.");
12630                pw.println("  -d: include dalvik details when dumping process details.");
12631                pw.println("  -c: dump in a compact machine-parseable representation.");
12632                pw.println("  --oom: only show processes organized by oom adj.");
12633                pw.println("  --local: only collect details locally, don't call process.");
12634                pw.println("If [process] is specified it can be the name or ");
12635                pw.println("pid of a specific process to dump.");
12636                return;
12637            } else {
12638                pw.println("Unknown argument: " + opt + "; use -h for help");
12639            }
12640        }
12641
12642        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12643        long uptime = SystemClock.uptimeMillis();
12644        long realtime = SystemClock.elapsedRealtime();
12645        final long[] tmpLong = new long[1];
12646
12647        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12648        if (procs == null) {
12649            // No Java processes.  Maybe they want to print a native process.
12650            if (args != null && args.length > opti
12651                    && args[opti].charAt(0) != '-') {
12652                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12653                        = new ArrayList<ProcessCpuTracker.Stats>();
12654                updateCpuStatsNow();
12655                int findPid = -1;
12656                try {
12657                    findPid = Integer.parseInt(args[opti]);
12658                } catch (NumberFormatException e) {
12659                }
12660                synchronized (mProcessCpuThread) {
12661                    final int N = mProcessCpuTracker.countStats();
12662                    for (int i=0; i<N; i++) {
12663                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12664                        if (st.pid == findPid || (st.baseName != null
12665                                && st.baseName.equals(args[opti]))) {
12666                            nativeProcs.add(st);
12667                        }
12668                    }
12669                }
12670                if (nativeProcs.size() > 0) {
12671                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12672                            isCompact);
12673                    Debug.MemoryInfo mi = null;
12674                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12675                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12676                        final int pid = r.pid;
12677                        if (!isCheckinRequest && dumpDetails) {
12678                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12679                        }
12680                        if (mi == null) {
12681                            mi = new Debug.MemoryInfo();
12682                        }
12683                        if (dumpDetails || (!brief && !oomOnly)) {
12684                            Debug.getMemoryInfo(pid, mi);
12685                        } else {
12686                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12687                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12688                        }
12689                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12690                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12691                        if (isCheckinRequest) {
12692                            pw.println();
12693                        }
12694                    }
12695                    return;
12696                }
12697            }
12698            pw.println("No process found for: " + args[opti]);
12699            return;
12700        }
12701
12702        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12703            dumpDetails = true;
12704        }
12705
12706        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12707
12708        String[] innerArgs = new String[args.length-opti];
12709        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12710
12711        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12712        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12713        long nativePss=0, dalvikPss=0, otherPss=0;
12714        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12715
12716        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12717        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12718                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12719
12720        long totalPss = 0;
12721        long cachedPss = 0;
12722
12723        Debug.MemoryInfo mi = null;
12724        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12725            final ProcessRecord r = procs.get(i);
12726            final IApplicationThread thread;
12727            final int pid;
12728            final int oomAdj;
12729            final boolean hasActivities;
12730            synchronized (this) {
12731                thread = r.thread;
12732                pid = r.pid;
12733                oomAdj = r.getSetAdjWithServices();
12734                hasActivities = r.activities.size() > 0;
12735            }
12736            if (thread != null) {
12737                if (!isCheckinRequest && dumpDetails) {
12738                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12739                }
12740                if (mi == null) {
12741                    mi = new Debug.MemoryInfo();
12742                }
12743                if (dumpDetails || (!brief && !oomOnly)) {
12744                    Debug.getMemoryInfo(pid, mi);
12745                } else {
12746                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12747                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12748                }
12749                if (dumpDetails) {
12750                    if (localOnly) {
12751                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12752                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12753                        if (isCheckinRequest) {
12754                            pw.println();
12755                        }
12756                    } else {
12757                        try {
12758                            pw.flush();
12759                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12760                                    dumpDalvik, innerArgs);
12761                        } catch (RemoteException e) {
12762                            if (!isCheckinRequest) {
12763                                pw.println("Got RemoteException!");
12764                                pw.flush();
12765                            }
12766                        }
12767                    }
12768                }
12769
12770                final long myTotalPss = mi.getTotalPss();
12771                final long myTotalUss = mi.getTotalUss();
12772
12773                synchronized (this) {
12774                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12775                        // Record this for posterity if the process has been stable.
12776                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12777                    }
12778                }
12779
12780                if (!isCheckinRequest && mi != null) {
12781                    totalPss += myTotalPss;
12782                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12783                            (hasActivities ? " / activities)" : ")"),
12784                            r.processName, myTotalPss, pid, hasActivities);
12785                    procMems.add(pssItem);
12786                    procMemsMap.put(pid, pssItem);
12787
12788                    nativePss += mi.nativePss;
12789                    dalvikPss += mi.dalvikPss;
12790                    otherPss += mi.otherPss;
12791                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12792                        long mem = mi.getOtherPss(j);
12793                        miscPss[j] += mem;
12794                        otherPss -= mem;
12795                    }
12796
12797                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12798                        cachedPss += myTotalPss;
12799                    }
12800
12801                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12802                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12803                                || oomIndex == (oomPss.length-1)) {
12804                            oomPss[oomIndex] += myTotalPss;
12805                            if (oomProcs[oomIndex] == null) {
12806                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12807                            }
12808                            oomProcs[oomIndex].add(pssItem);
12809                            break;
12810                        }
12811                    }
12812                }
12813            }
12814        }
12815
12816        long nativeProcTotalPss = 0;
12817
12818        if (!isCheckinRequest && procs.size() > 1) {
12819            // If we are showing aggregations, also look for native processes to
12820            // include so that our aggregations are more accurate.
12821            updateCpuStatsNow();
12822            synchronized (mProcessCpuThread) {
12823                final int N = mProcessCpuTracker.countStats();
12824                for (int i=0; i<N; i++) {
12825                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12826                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12827                        if (mi == null) {
12828                            mi = new Debug.MemoryInfo();
12829                        }
12830                        if (!brief && !oomOnly) {
12831                            Debug.getMemoryInfo(st.pid, mi);
12832                        } else {
12833                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12834                            mi.nativePrivateDirty = (int)tmpLong[0];
12835                        }
12836
12837                        final long myTotalPss = mi.getTotalPss();
12838                        totalPss += myTotalPss;
12839                        nativeProcTotalPss += myTotalPss;
12840
12841                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12842                                st.name, myTotalPss, st.pid, false);
12843                        procMems.add(pssItem);
12844
12845                        nativePss += mi.nativePss;
12846                        dalvikPss += mi.dalvikPss;
12847                        otherPss += mi.otherPss;
12848                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12849                            long mem = mi.getOtherPss(j);
12850                            miscPss[j] += mem;
12851                            otherPss -= mem;
12852                        }
12853                        oomPss[0] += myTotalPss;
12854                        if (oomProcs[0] == null) {
12855                            oomProcs[0] = new ArrayList<MemItem>();
12856                        }
12857                        oomProcs[0].add(pssItem);
12858                    }
12859                }
12860            }
12861
12862            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12863
12864            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12865            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12866            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12867            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12868                String label = Debug.MemoryInfo.getOtherLabel(j);
12869                catMems.add(new MemItem(label, label, miscPss[j], j));
12870            }
12871
12872            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12873            for (int j=0; j<oomPss.length; j++) {
12874                if (oomPss[j] != 0) {
12875                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12876                            : DUMP_MEM_OOM_LABEL[j];
12877                    MemItem item = new MemItem(label, label, oomPss[j],
12878                            DUMP_MEM_OOM_ADJ[j]);
12879                    item.subitems = oomProcs[j];
12880                    oomMems.add(item);
12881                }
12882            }
12883
12884            if (!brief && !oomOnly && !isCompact) {
12885                pw.println();
12886                pw.println("Total PSS by process:");
12887                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12888                pw.println();
12889            }
12890            if (!isCompact) {
12891                pw.println("Total PSS by OOM adjustment:");
12892            }
12893            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12894            if (!brief && !oomOnly) {
12895                PrintWriter out = categoryPw != null ? categoryPw : pw;
12896                if (!isCompact) {
12897                    out.println();
12898                    out.println("Total PSS by category:");
12899                }
12900                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12901            }
12902            if (!isCompact) {
12903                pw.println();
12904            }
12905            MemInfoReader memInfo = new MemInfoReader();
12906            memInfo.readMemInfo();
12907            if (nativeProcTotalPss > 0) {
12908                synchronized (this) {
12909                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12910                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12911                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12912                            nativeProcTotalPss);
12913                }
12914            }
12915            if (!brief) {
12916                if (!isCompact) {
12917                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12918                    pw.print(" kB (status ");
12919                    switch (mLastMemoryLevel) {
12920                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12921                            pw.println("normal)");
12922                            break;
12923                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12924                            pw.println("moderate)");
12925                            break;
12926                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12927                            pw.println("low)");
12928                            break;
12929                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12930                            pw.println("critical)");
12931                            break;
12932                        default:
12933                            pw.print(mLastMemoryLevel);
12934                            pw.println(")");
12935                            break;
12936                    }
12937                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12938                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12939                            pw.print(cachedPss); pw.print(" cached pss + ");
12940                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12941                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12942                } else {
12943                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12944                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12945                            + memInfo.getFreeSizeKb()); pw.print(",");
12946                    pw.println(totalPss - cachedPss);
12947                }
12948            }
12949            if (!isCompact) {
12950                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12951                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12952                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12953                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12954                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12955                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12956                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12957                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12958                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12959                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12960                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12961            }
12962            if (!brief) {
12963                if (memInfo.getZramTotalSizeKb() != 0) {
12964                    if (!isCompact) {
12965                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12966                                pw.print(" kB physical used for ");
12967                                pw.print(memInfo.getSwapTotalSizeKb()
12968                                        - memInfo.getSwapFreeSizeKb());
12969                                pw.print(" kB in swap (");
12970                                pw.print(memInfo.getSwapTotalSizeKb());
12971                                pw.println(" kB total swap)");
12972                    } else {
12973                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12974                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12975                                pw.println(memInfo.getSwapFreeSizeKb());
12976                    }
12977                }
12978                final int[] SINGLE_LONG_FORMAT = new int[] {
12979                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12980                };
12981                long[] longOut = new long[1];
12982                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12983                        SINGLE_LONG_FORMAT, null, longOut, null);
12984                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12985                longOut[0] = 0;
12986                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12987                        SINGLE_LONG_FORMAT, null, longOut, null);
12988                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12989                longOut[0] = 0;
12990                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12991                        SINGLE_LONG_FORMAT, null, longOut, null);
12992                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12993                longOut[0] = 0;
12994                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12995                        SINGLE_LONG_FORMAT, null, longOut, null);
12996                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12997                if (!isCompact) {
12998                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12999                        pw.print("      KSM: "); pw.print(sharing);
13000                                pw.print(" kB saved from shared ");
13001                                pw.print(shared); pw.println(" kB");
13002                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13003                                pw.print(voltile); pw.println(" kB volatile");
13004                    }
13005                    pw.print("   Tuning: ");
13006                    pw.print(ActivityManager.staticGetMemoryClass());
13007                    pw.print(" (large ");
13008                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13009                    pw.print("), oom ");
13010                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13011                    pw.print(" kB");
13012                    pw.print(", restore limit ");
13013                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13014                    pw.print(" kB");
13015                    if (ActivityManager.isLowRamDeviceStatic()) {
13016                        pw.print(" (low-ram)");
13017                    }
13018                    if (ActivityManager.isHighEndGfx()) {
13019                        pw.print(" (high-end-gfx)");
13020                    }
13021                    pw.println();
13022                } else {
13023                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13024                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13025                    pw.println(voltile);
13026                    pw.print("tuning,");
13027                    pw.print(ActivityManager.staticGetMemoryClass());
13028                    pw.print(',');
13029                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13030                    pw.print(',');
13031                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13032                    if (ActivityManager.isLowRamDeviceStatic()) {
13033                        pw.print(",low-ram");
13034                    }
13035                    if (ActivityManager.isHighEndGfx()) {
13036                        pw.print(",high-end-gfx");
13037                    }
13038                    pw.println();
13039                }
13040            }
13041        }
13042    }
13043
13044    /**
13045     * Searches array of arguments for the specified string
13046     * @param args array of argument strings
13047     * @param value value to search for
13048     * @return true if the value is contained in the array
13049     */
13050    private static boolean scanArgs(String[] args, String value) {
13051        if (args != null) {
13052            for (String arg : args) {
13053                if (value.equals(arg)) {
13054                    return true;
13055                }
13056            }
13057        }
13058        return false;
13059    }
13060
13061    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13062            ContentProviderRecord cpr, boolean always) {
13063        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13064
13065        if (!inLaunching || always) {
13066            synchronized (cpr) {
13067                cpr.launchingApp = null;
13068                cpr.notifyAll();
13069            }
13070            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13071            String names[] = cpr.info.authority.split(";");
13072            for (int j = 0; j < names.length; j++) {
13073                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13074            }
13075        }
13076
13077        for (int i=0; i<cpr.connections.size(); i++) {
13078            ContentProviderConnection conn = cpr.connections.get(i);
13079            if (conn.waiting) {
13080                // If this connection is waiting for the provider, then we don't
13081                // need to mess with its process unless we are always removing
13082                // or for some reason the provider is not currently launching.
13083                if (inLaunching && !always) {
13084                    continue;
13085                }
13086            }
13087            ProcessRecord capp = conn.client;
13088            conn.dead = true;
13089            if (conn.stableCount > 0) {
13090                if (!capp.persistent && capp.thread != null
13091                        && capp.pid != 0
13092                        && capp.pid != MY_PID) {
13093                    killUnneededProcessLocked(capp, "depends on provider "
13094                            + cpr.name.flattenToShortString()
13095                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13096                }
13097            } else if (capp.thread != null && conn.provider.provider != null) {
13098                try {
13099                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13100                } catch (RemoteException e) {
13101                }
13102                // In the protocol here, we don't expect the client to correctly
13103                // clean up this connection, we'll just remove it.
13104                cpr.connections.remove(i);
13105                conn.client.conProviders.remove(conn);
13106            }
13107        }
13108
13109        if (inLaunching && always) {
13110            mLaunchingProviders.remove(cpr);
13111        }
13112        return inLaunching;
13113    }
13114
13115    /**
13116     * Main code for cleaning up a process when it has gone away.  This is
13117     * called both as a result of the process dying, or directly when stopping
13118     * a process when running in single process mode.
13119     */
13120    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13121            boolean restarting, boolean allowRestart, int index) {
13122        if (index >= 0) {
13123            removeLruProcessLocked(app);
13124            ProcessList.remove(app.pid);
13125        }
13126
13127        mProcessesToGc.remove(app);
13128        mPendingPssProcesses.remove(app);
13129
13130        // Dismiss any open dialogs.
13131        if (app.crashDialog != null && !app.forceCrashReport) {
13132            app.crashDialog.dismiss();
13133            app.crashDialog = null;
13134        }
13135        if (app.anrDialog != null) {
13136            app.anrDialog.dismiss();
13137            app.anrDialog = null;
13138        }
13139        if (app.waitDialog != null) {
13140            app.waitDialog.dismiss();
13141            app.waitDialog = null;
13142        }
13143
13144        app.crashing = false;
13145        app.notResponding = false;
13146
13147        app.resetPackageList(mProcessStats);
13148        app.unlinkDeathRecipient();
13149        app.makeInactive(mProcessStats);
13150        app.waitingToKill = null;
13151        app.forcingToForeground = null;
13152        updateProcessForegroundLocked(app, false, false);
13153        app.foregroundActivities = false;
13154        app.hasShownUi = false;
13155        app.treatLikeActivity = false;
13156        app.hasAboveClient = false;
13157        app.hasClientActivities = false;
13158
13159        mServices.killServicesLocked(app, allowRestart);
13160
13161        boolean restart = false;
13162
13163        // Remove published content providers.
13164        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13165            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13166            final boolean always = app.bad || !allowRestart;
13167            if (removeDyingProviderLocked(app, cpr, always) || always) {
13168                // We left the provider in the launching list, need to
13169                // restart it.
13170                restart = true;
13171            }
13172
13173            cpr.provider = null;
13174            cpr.proc = null;
13175        }
13176        app.pubProviders.clear();
13177
13178        // Take care of any launching providers waiting for this process.
13179        if (checkAppInLaunchingProvidersLocked(app, false)) {
13180            restart = true;
13181        }
13182
13183        // Unregister from connected content providers.
13184        if (!app.conProviders.isEmpty()) {
13185            for (int i=0; i<app.conProviders.size(); i++) {
13186                ContentProviderConnection conn = app.conProviders.get(i);
13187                conn.provider.connections.remove(conn);
13188            }
13189            app.conProviders.clear();
13190        }
13191
13192        // At this point there may be remaining entries in mLaunchingProviders
13193        // where we were the only one waiting, so they are no longer of use.
13194        // Look for these and clean up if found.
13195        // XXX Commented out for now.  Trying to figure out a way to reproduce
13196        // the actual situation to identify what is actually going on.
13197        if (false) {
13198            for (int i=0; i<mLaunchingProviders.size(); i++) {
13199                ContentProviderRecord cpr = (ContentProviderRecord)
13200                        mLaunchingProviders.get(i);
13201                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13202                    synchronized (cpr) {
13203                        cpr.launchingApp = null;
13204                        cpr.notifyAll();
13205                    }
13206                }
13207            }
13208        }
13209
13210        skipCurrentReceiverLocked(app);
13211
13212        // Unregister any receivers.
13213        for (int i=app.receivers.size()-1; i>=0; i--) {
13214            removeReceiverLocked(app.receivers.valueAt(i));
13215        }
13216        app.receivers.clear();
13217
13218        // If the app is undergoing backup, tell the backup manager about it
13219        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13220            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13221                    + mBackupTarget.appInfo + " died during backup");
13222            try {
13223                IBackupManager bm = IBackupManager.Stub.asInterface(
13224                        ServiceManager.getService(Context.BACKUP_SERVICE));
13225                bm.agentDisconnected(app.info.packageName);
13226            } catch (RemoteException e) {
13227                // can't happen; backup manager is local
13228            }
13229        }
13230
13231        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13232            ProcessChangeItem item = mPendingProcessChanges.get(i);
13233            if (item.pid == app.pid) {
13234                mPendingProcessChanges.remove(i);
13235                mAvailProcessChanges.add(item);
13236            }
13237        }
13238        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13239
13240        // If the caller is restarting this app, then leave it in its
13241        // current lists and let the caller take care of it.
13242        if (restarting) {
13243            return;
13244        }
13245
13246        if (!app.persistent || app.isolated) {
13247            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13248                    "Removing non-persistent process during cleanup: " + app);
13249            mProcessNames.remove(app.processName, app.uid);
13250            mIsolatedProcesses.remove(app.uid);
13251            if (mHeavyWeightProcess == app) {
13252                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13253                        mHeavyWeightProcess.userId, 0));
13254                mHeavyWeightProcess = null;
13255            }
13256        } else if (!app.removed) {
13257            // This app is persistent, so we need to keep its record around.
13258            // If it is not already on the pending app list, add it there
13259            // and start a new process for it.
13260            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13261                mPersistentStartingProcesses.add(app);
13262                restart = true;
13263            }
13264        }
13265        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13266                "Clean-up removing on hold: " + app);
13267        mProcessesOnHold.remove(app);
13268
13269        if (app == mHomeProcess) {
13270            mHomeProcess = null;
13271        }
13272        if (app == mPreviousProcess) {
13273            mPreviousProcess = null;
13274        }
13275
13276        if (restart && !app.isolated) {
13277            // We have components that still need to be running in the
13278            // process, so re-launch it.
13279            mProcessNames.put(app.processName, app.uid, app);
13280            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13281        } else if (app.pid > 0 && app.pid != MY_PID) {
13282            // Goodbye!
13283            boolean removed;
13284            synchronized (mPidsSelfLocked) {
13285                mPidsSelfLocked.remove(app.pid);
13286                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13287            }
13288            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13289                    app.processName, app.info.uid);
13290            if (app.isolated) {
13291                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13292            }
13293            app.setPid(0);
13294        }
13295    }
13296
13297    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13298        // Look through the content providers we are waiting to have launched,
13299        // and if any run in this process then either schedule a restart of
13300        // the process or kill the client waiting for it if this process has
13301        // gone bad.
13302        int NL = mLaunchingProviders.size();
13303        boolean restart = false;
13304        for (int i=0; i<NL; i++) {
13305            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13306            if (cpr.launchingApp == app) {
13307                if (!alwaysBad && !app.bad) {
13308                    restart = true;
13309                } else {
13310                    removeDyingProviderLocked(app, cpr, true);
13311                    // cpr should have been removed from mLaunchingProviders
13312                    NL = mLaunchingProviders.size();
13313                    i--;
13314                }
13315            }
13316        }
13317        return restart;
13318    }
13319
13320    // =========================================================
13321    // SERVICES
13322    // =========================================================
13323
13324    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13325            int flags) {
13326        enforceNotIsolatedCaller("getServices");
13327        synchronized (this) {
13328            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13329        }
13330    }
13331
13332    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13333        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13334        synchronized (this) {
13335            return mServices.getRunningServiceControlPanelLocked(name);
13336        }
13337    }
13338
13339    public ComponentName startService(IApplicationThread caller, Intent service,
13340            String resolvedType, int userId) {
13341        enforceNotIsolatedCaller("startService");
13342        // Refuse possible leaked file descriptors
13343        if (service != null && service.hasFileDescriptors() == true) {
13344            throw new IllegalArgumentException("File descriptors passed in Intent");
13345        }
13346
13347        if (DEBUG_SERVICE)
13348            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13349        synchronized(this) {
13350            final int callingPid = Binder.getCallingPid();
13351            final int callingUid = Binder.getCallingUid();
13352            final long origId = Binder.clearCallingIdentity();
13353            ComponentName res = mServices.startServiceLocked(caller, service,
13354                    resolvedType, callingPid, callingUid, userId);
13355            Binder.restoreCallingIdentity(origId);
13356            return res;
13357        }
13358    }
13359
13360    ComponentName startServiceInPackage(int uid,
13361            Intent service, String resolvedType, int userId) {
13362        synchronized(this) {
13363            if (DEBUG_SERVICE)
13364                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13365            final long origId = Binder.clearCallingIdentity();
13366            ComponentName res = mServices.startServiceLocked(null, service,
13367                    resolvedType, -1, uid, userId);
13368            Binder.restoreCallingIdentity(origId);
13369            return res;
13370        }
13371    }
13372
13373    public int stopService(IApplicationThread caller, Intent service,
13374            String resolvedType, int userId) {
13375        enforceNotIsolatedCaller("stopService");
13376        // Refuse possible leaked file descriptors
13377        if (service != null && service.hasFileDescriptors() == true) {
13378            throw new IllegalArgumentException("File descriptors passed in Intent");
13379        }
13380
13381        synchronized(this) {
13382            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13383        }
13384    }
13385
13386    public IBinder peekService(Intent service, String resolvedType) {
13387        enforceNotIsolatedCaller("peekService");
13388        // Refuse possible leaked file descriptors
13389        if (service != null && service.hasFileDescriptors() == true) {
13390            throw new IllegalArgumentException("File descriptors passed in Intent");
13391        }
13392        synchronized(this) {
13393            return mServices.peekServiceLocked(service, resolvedType);
13394        }
13395    }
13396
13397    public boolean stopServiceToken(ComponentName className, IBinder token,
13398            int startId) {
13399        synchronized(this) {
13400            return mServices.stopServiceTokenLocked(className, token, startId);
13401        }
13402    }
13403
13404    public void setServiceForeground(ComponentName className, IBinder token,
13405            int id, Notification notification, boolean removeNotification) {
13406        synchronized(this) {
13407            mServices.setServiceForegroundLocked(className, token, id, notification,
13408                    removeNotification);
13409        }
13410    }
13411
13412    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13413            boolean requireFull, String name, String callerPackage) {
13414        final int callingUserId = UserHandle.getUserId(callingUid);
13415        if (callingUserId != userId) {
13416            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13417                if ((requireFull || checkComponentPermission(
13418                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13419                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13420                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13421                                callingPid, callingUid, -1, true)
13422                                != PackageManager.PERMISSION_GRANTED) {
13423                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13424                        // In this case, they would like to just execute as their
13425                        // owner user instead of failing.
13426                        userId = callingUserId;
13427                    } else {
13428                        StringBuilder builder = new StringBuilder(128);
13429                        builder.append("Permission Denial: ");
13430                        builder.append(name);
13431                        if (callerPackage != null) {
13432                            builder.append(" from ");
13433                            builder.append(callerPackage);
13434                        }
13435                        builder.append(" asks to run as user ");
13436                        builder.append(userId);
13437                        builder.append(" but is calling from user ");
13438                        builder.append(UserHandle.getUserId(callingUid));
13439                        builder.append("; this requires ");
13440                        builder.append(INTERACT_ACROSS_USERS_FULL);
13441                        if (!requireFull) {
13442                            builder.append(" or ");
13443                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13444                        }
13445                        String msg = builder.toString();
13446                        Slog.w(TAG, msg);
13447                        throw new SecurityException(msg);
13448                    }
13449                }
13450            }
13451            if (userId == UserHandle.USER_CURRENT
13452                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13453                // Note that we may be accessing this outside of a lock...
13454                // shouldn't be a big deal, if this is being called outside
13455                // of a locked context there is intrinsically a race with
13456                // the value the caller will receive and someone else changing it.
13457                userId = mCurrentUserId;
13458            }
13459            if (!allowAll && userId < 0) {
13460                throw new IllegalArgumentException(
13461                        "Call does not support special user #" + userId);
13462            }
13463        }
13464        return userId;
13465    }
13466
13467    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13468            String className, int flags) {
13469        boolean result = false;
13470        // For apps that don't have pre-defined UIDs, check for permission
13471        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13472            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13473                if (ActivityManager.checkUidPermission(
13474                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13475                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13476                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13477                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13478                            + " requests FLAG_SINGLE_USER, but app does not hold "
13479                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13480                    Slog.w(TAG, msg);
13481                    throw new SecurityException(msg);
13482                }
13483                // Permission passed
13484                result = true;
13485            }
13486        } else if ("system".equals(componentProcessName)) {
13487            result = true;
13488        } else {
13489            // App with pre-defined UID, check if it's a persistent app
13490            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13491        }
13492        if (DEBUG_MU) {
13493            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13494                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13495        }
13496        return result;
13497    }
13498
13499    /**
13500     * Checks to see if the caller is in the same app as the singleton
13501     * component, or the component is in a special app. It allows special apps
13502     * to export singleton components but prevents exporting singleton
13503     * components for regular apps.
13504     */
13505    boolean isValidSingletonCall(int callingUid, int componentUid) {
13506        int componentAppId = UserHandle.getAppId(componentUid);
13507        return UserHandle.isSameApp(callingUid, componentUid)
13508                || componentAppId == Process.SYSTEM_UID
13509                || componentAppId == Process.PHONE_UID
13510                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13511                        == PackageManager.PERMISSION_GRANTED;
13512    }
13513
13514    public int bindService(IApplicationThread caller, IBinder token,
13515            Intent service, String resolvedType,
13516            IServiceConnection connection, int flags, int userId) {
13517        enforceNotIsolatedCaller("bindService");
13518        // Refuse possible leaked file descriptors
13519        if (service != null && service.hasFileDescriptors() == true) {
13520            throw new IllegalArgumentException("File descriptors passed in Intent");
13521        }
13522
13523        synchronized(this) {
13524            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13525                    connection, flags, userId);
13526        }
13527    }
13528
13529    public boolean unbindService(IServiceConnection connection) {
13530        synchronized (this) {
13531            return mServices.unbindServiceLocked(connection);
13532        }
13533    }
13534
13535    public void publishService(IBinder token, Intent intent, IBinder service) {
13536        // Refuse possible leaked file descriptors
13537        if (intent != null && intent.hasFileDescriptors() == true) {
13538            throw new IllegalArgumentException("File descriptors passed in Intent");
13539        }
13540
13541        synchronized(this) {
13542            if (!(token instanceof ServiceRecord)) {
13543                throw new IllegalArgumentException("Invalid service token");
13544            }
13545            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13546        }
13547    }
13548
13549    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13550        // Refuse possible leaked file descriptors
13551        if (intent != null && intent.hasFileDescriptors() == true) {
13552            throw new IllegalArgumentException("File descriptors passed in Intent");
13553        }
13554
13555        synchronized(this) {
13556            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13557        }
13558    }
13559
13560    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13561        synchronized(this) {
13562            if (!(token instanceof ServiceRecord)) {
13563                throw new IllegalArgumentException("Invalid service token");
13564            }
13565            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13566        }
13567    }
13568
13569    // =========================================================
13570    // BACKUP AND RESTORE
13571    // =========================================================
13572
13573    // Cause the target app to be launched if necessary and its backup agent
13574    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13575    // activity manager to announce its creation.
13576    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13577        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13578        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13579
13580        synchronized(this) {
13581            // !!! TODO: currently no check here that we're already bound
13582            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13583            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13584            synchronized (stats) {
13585                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13586            }
13587
13588            // Backup agent is now in use, its package can't be stopped.
13589            try {
13590                AppGlobals.getPackageManager().setPackageStoppedState(
13591                        app.packageName, false, UserHandle.getUserId(app.uid));
13592            } catch (RemoteException e) {
13593            } catch (IllegalArgumentException e) {
13594                Slog.w(TAG, "Failed trying to unstop package "
13595                        + app.packageName + ": " + e);
13596            }
13597
13598            BackupRecord r = new BackupRecord(ss, app, backupMode);
13599            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13600                    ? new ComponentName(app.packageName, app.backupAgentName)
13601                    : new ComponentName("android", "FullBackupAgent");
13602            // startProcessLocked() returns existing proc's record if it's already running
13603            ProcessRecord proc = startProcessLocked(app.processName, app,
13604                    false, 0, "backup", hostingName, false, false, false);
13605            if (proc == null) {
13606                Slog.e(TAG, "Unable to start backup agent process " + r);
13607                return false;
13608            }
13609
13610            r.app = proc;
13611            mBackupTarget = r;
13612            mBackupAppName = app.packageName;
13613
13614            // Try not to kill the process during backup
13615            updateOomAdjLocked(proc);
13616
13617            // If the process is already attached, schedule the creation of the backup agent now.
13618            // If it is not yet live, this will be done when it attaches to the framework.
13619            if (proc.thread != null) {
13620                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13621                try {
13622                    proc.thread.scheduleCreateBackupAgent(app,
13623                            compatibilityInfoForPackageLocked(app), backupMode);
13624                } catch (RemoteException e) {
13625                    // Will time out on the backup manager side
13626                }
13627            } else {
13628                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13629            }
13630            // Invariants: at this point, the target app process exists and the application
13631            // is either already running or in the process of coming up.  mBackupTarget and
13632            // mBackupAppName describe the app, so that when it binds back to the AM we
13633            // know that it's scheduled for a backup-agent operation.
13634        }
13635
13636        return true;
13637    }
13638
13639    @Override
13640    public void clearPendingBackup() {
13641        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13642        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13643
13644        synchronized (this) {
13645            mBackupTarget = null;
13646            mBackupAppName = null;
13647        }
13648    }
13649
13650    // A backup agent has just come up
13651    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13652        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13653                + " = " + agent);
13654
13655        synchronized(this) {
13656            if (!agentPackageName.equals(mBackupAppName)) {
13657                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13658                return;
13659            }
13660        }
13661
13662        long oldIdent = Binder.clearCallingIdentity();
13663        try {
13664            IBackupManager bm = IBackupManager.Stub.asInterface(
13665                    ServiceManager.getService(Context.BACKUP_SERVICE));
13666            bm.agentConnected(agentPackageName, agent);
13667        } catch (RemoteException e) {
13668            // can't happen; the backup manager service is local
13669        } catch (Exception e) {
13670            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13671            e.printStackTrace();
13672        } finally {
13673            Binder.restoreCallingIdentity(oldIdent);
13674        }
13675    }
13676
13677    // done with this agent
13678    public void unbindBackupAgent(ApplicationInfo appInfo) {
13679        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13680        if (appInfo == null) {
13681            Slog.w(TAG, "unbind backup agent for null app");
13682            return;
13683        }
13684
13685        synchronized(this) {
13686            try {
13687                if (mBackupAppName == null) {
13688                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13689                    return;
13690                }
13691
13692                if (!mBackupAppName.equals(appInfo.packageName)) {
13693                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13694                    return;
13695                }
13696
13697                // Not backing this app up any more; reset its OOM adjustment
13698                final ProcessRecord proc = mBackupTarget.app;
13699                updateOomAdjLocked(proc);
13700
13701                // If the app crashed during backup, 'thread' will be null here
13702                if (proc.thread != null) {
13703                    try {
13704                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13705                                compatibilityInfoForPackageLocked(appInfo));
13706                    } catch (Exception e) {
13707                        Slog.e(TAG, "Exception when unbinding backup agent:");
13708                        e.printStackTrace();
13709                    }
13710                }
13711            } finally {
13712                mBackupTarget = null;
13713                mBackupAppName = null;
13714            }
13715        }
13716    }
13717    // =========================================================
13718    // BROADCASTS
13719    // =========================================================
13720
13721    private final List getStickiesLocked(String action, IntentFilter filter,
13722            List cur, int userId) {
13723        final ContentResolver resolver = mContext.getContentResolver();
13724        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13725        if (stickies == null) {
13726            return cur;
13727        }
13728        final ArrayList<Intent> list = stickies.get(action);
13729        if (list == null) {
13730            return cur;
13731        }
13732        int N = list.size();
13733        for (int i=0; i<N; i++) {
13734            Intent intent = list.get(i);
13735            if (filter.match(resolver, intent, true, TAG) >= 0) {
13736                if (cur == null) {
13737                    cur = new ArrayList<Intent>();
13738                }
13739                cur.add(intent);
13740            }
13741        }
13742        return cur;
13743    }
13744
13745    boolean isPendingBroadcastProcessLocked(int pid) {
13746        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13747                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13748    }
13749
13750    void skipPendingBroadcastLocked(int pid) {
13751            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13752            for (BroadcastQueue queue : mBroadcastQueues) {
13753                queue.skipPendingBroadcastLocked(pid);
13754            }
13755    }
13756
13757    // The app just attached; send any pending broadcasts that it should receive
13758    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13759        boolean didSomething = false;
13760        for (BroadcastQueue queue : mBroadcastQueues) {
13761            didSomething |= queue.sendPendingBroadcastsLocked(app);
13762        }
13763        return didSomething;
13764    }
13765
13766    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13767            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13768        enforceNotIsolatedCaller("registerReceiver");
13769        int callingUid;
13770        int callingPid;
13771        synchronized(this) {
13772            ProcessRecord callerApp = null;
13773            if (caller != null) {
13774                callerApp = getRecordForAppLocked(caller);
13775                if (callerApp == null) {
13776                    throw new SecurityException(
13777                            "Unable to find app for caller " + caller
13778                            + " (pid=" + Binder.getCallingPid()
13779                            + ") when registering receiver " + receiver);
13780                }
13781                if (callerApp.info.uid != Process.SYSTEM_UID &&
13782                        !callerApp.pkgList.containsKey(callerPackage) &&
13783                        !"android".equals(callerPackage)) {
13784                    throw new SecurityException("Given caller package " + callerPackage
13785                            + " is not running in process " + callerApp);
13786                }
13787                callingUid = callerApp.info.uid;
13788                callingPid = callerApp.pid;
13789            } else {
13790                callerPackage = null;
13791                callingUid = Binder.getCallingUid();
13792                callingPid = Binder.getCallingPid();
13793            }
13794
13795            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13796                    true, true, "registerReceiver", callerPackage);
13797
13798            List allSticky = null;
13799
13800            // Look for any matching sticky broadcasts...
13801            Iterator actions = filter.actionsIterator();
13802            if (actions != null) {
13803                while (actions.hasNext()) {
13804                    String action = (String)actions.next();
13805                    allSticky = getStickiesLocked(action, filter, allSticky,
13806                            UserHandle.USER_ALL);
13807                    allSticky = getStickiesLocked(action, filter, allSticky,
13808                            UserHandle.getUserId(callingUid));
13809                }
13810            } else {
13811                allSticky = getStickiesLocked(null, filter, allSticky,
13812                        UserHandle.USER_ALL);
13813                allSticky = getStickiesLocked(null, filter, allSticky,
13814                        UserHandle.getUserId(callingUid));
13815            }
13816
13817            // The first sticky in the list is returned directly back to
13818            // the client.
13819            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13820
13821            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13822                    + ": " + sticky);
13823
13824            if (receiver == null) {
13825                return sticky;
13826            }
13827
13828            ReceiverList rl
13829                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13830            if (rl == null) {
13831                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13832                        userId, receiver);
13833                if (rl.app != null) {
13834                    rl.app.receivers.add(rl);
13835                } else {
13836                    try {
13837                        receiver.asBinder().linkToDeath(rl, 0);
13838                    } catch (RemoteException e) {
13839                        return sticky;
13840                    }
13841                    rl.linkedToDeath = true;
13842                }
13843                mRegisteredReceivers.put(receiver.asBinder(), rl);
13844            } else if (rl.uid != callingUid) {
13845                throw new IllegalArgumentException(
13846                        "Receiver requested to register for uid " + callingUid
13847                        + " was previously registered for uid " + rl.uid);
13848            } else if (rl.pid != callingPid) {
13849                throw new IllegalArgumentException(
13850                        "Receiver requested to register for pid " + callingPid
13851                        + " was previously registered for pid " + rl.pid);
13852            } else if (rl.userId != userId) {
13853                throw new IllegalArgumentException(
13854                        "Receiver requested to register for user " + userId
13855                        + " was previously registered for user " + rl.userId);
13856            }
13857            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13858                    permission, callingUid, userId);
13859            rl.add(bf);
13860            if (!bf.debugCheck()) {
13861                Slog.w(TAG, "==> For Dynamic broadast");
13862            }
13863            mReceiverResolver.addFilter(bf);
13864
13865            // Enqueue broadcasts for all existing stickies that match
13866            // this filter.
13867            if (allSticky != null) {
13868                ArrayList receivers = new ArrayList();
13869                receivers.add(bf);
13870
13871                int N = allSticky.size();
13872                for (int i=0; i<N; i++) {
13873                    Intent intent = (Intent)allSticky.get(i);
13874                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13875                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13876                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13877                            null, null, false, true, true, -1);
13878                    queue.enqueueParallelBroadcastLocked(r);
13879                    queue.scheduleBroadcastsLocked();
13880                }
13881            }
13882
13883            return sticky;
13884        }
13885    }
13886
13887    public void unregisterReceiver(IIntentReceiver receiver) {
13888        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13889
13890        final long origId = Binder.clearCallingIdentity();
13891        try {
13892            boolean doTrim = false;
13893
13894            synchronized(this) {
13895                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13896                if (rl != null) {
13897                    if (rl.curBroadcast != null) {
13898                        BroadcastRecord r = rl.curBroadcast;
13899                        final boolean doNext = finishReceiverLocked(
13900                                receiver.asBinder(), r.resultCode, r.resultData,
13901                                r.resultExtras, r.resultAbort);
13902                        if (doNext) {
13903                            doTrim = true;
13904                            r.queue.processNextBroadcast(false);
13905                        }
13906                    }
13907
13908                    if (rl.app != null) {
13909                        rl.app.receivers.remove(rl);
13910                    }
13911                    removeReceiverLocked(rl);
13912                    if (rl.linkedToDeath) {
13913                        rl.linkedToDeath = false;
13914                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13915                    }
13916                }
13917            }
13918
13919            // If we actually concluded any broadcasts, we might now be able
13920            // to trim the recipients' apps from our working set
13921            if (doTrim) {
13922                trimApplications();
13923                return;
13924            }
13925
13926        } finally {
13927            Binder.restoreCallingIdentity(origId);
13928        }
13929    }
13930
13931    void removeReceiverLocked(ReceiverList rl) {
13932        mRegisteredReceivers.remove(rl.receiver.asBinder());
13933        int N = rl.size();
13934        for (int i=0; i<N; i++) {
13935            mReceiverResolver.removeFilter(rl.get(i));
13936        }
13937    }
13938
13939    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13940        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13941            ProcessRecord r = mLruProcesses.get(i);
13942            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13943                try {
13944                    r.thread.dispatchPackageBroadcast(cmd, packages);
13945                } catch (RemoteException ex) {
13946                }
13947            }
13948        }
13949    }
13950
13951    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13952            int[] users) {
13953        List<ResolveInfo> receivers = null;
13954        try {
13955            HashSet<ComponentName> singleUserReceivers = null;
13956            boolean scannedFirstReceivers = false;
13957            for (int user : users) {
13958                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13959                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13960                if (user != 0 && newReceivers != null) {
13961                    // If this is not the primary user, we need to check for
13962                    // any receivers that should be filtered out.
13963                    for (int i=0; i<newReceivers.size(); i++) {
13964                        ResolveInfo ri = newReceivers.get(i);
13965                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13966                            newReceivers.remove(i);
13967                            i--;
13968                        }
13969                    }
13970                }
13971                if (newReceivers != null && newReceivers.size() == 0) {
13972                    newReceivers = null;
13973                }
13974                if (receivers == null) {
13975                    receivers = newReceivers;
13976                } else if (newReceivers != null) {
13977                    // We need to concatenate the additional receivers
13978                    // found with what we have do far.  This would be easy,
13979                    // but we also need to de-dup any receivers that are
13980                    // singleUser.
13981                    if (!scannedFirstReceivers) {
13982                        // Collect any single user receivers we had already retrieved.
13983                        scannedFirstReceivers = true;
13984                        for (int i=0; i<receivers.size(); i++) {
13985                            ResolveInfo ri = receivers.get(i);
13986                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13987                                ComponentName cn = new ComponentName(
13988                                        ri.activityInfo.packageName, ri.activityInfo.name);
13989                                if (singleUserReceivers == null) {
13990                                    singleUserReceivers = new HashSet<ComponentName>();
13991                                }
13992                                singleUserReceivers.add(cn);
13993                            }
13994                        }
13995                    }
13996                    // Add the new results to the existing results, tracking
13997                    // and de-dupping single user receivers.
13998                    for (int i=0; i<newReceivers.size(); i++) {
13999                        ResolveInfo ri = newReceivers.get(i);
14000                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14001                            ComponentName cn = new ComponentName(
14002                                    ri.activityInfo.packageName, ri.activityInfo.name);
14003                            if (singleUserReceivers == null) {
14004                                singleUserReceivers = new HashSet<ComponentName>();
14005                            }
14006                            if (!singleUserReceivers.contains(cn)) {
14007                                singleUserReceivers.add(cn);
14008                                receivers.add(ri);
14009                            }
14010                        } else {
14011                            receivers.add(ri);
14012                        }
14013                    }
14014                }
14015            }
14016        } catch (RemoteException ex) {
14017            // pm is in same process, this will never happen.
14018        }
14019        return receivers;
14020    }
14021
14022    private final int broadcastIntentLocked(ProcessRecord callerApp,
14023            String callerPackage, Intent intent, String resolvedType,
14024            IIntentReceiver resultTo, int resultCode, String resultData,
14025            Bundle map, String requiredPermission, int appOp,
14026            boolean ordered, boolean sticky, int callingPid, int callingUid,
14027            int userId) {
14028        intent = new Intent(intent);
14029
14030        // By default broadcasts do not go to stopped apps.
14031        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14032
14033        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14034            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14035            + " ordered=" + ordered + " userid=" + userId);
14036        if ((resultTo != null) && !ordered) {
14037            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14038        }
14039
14040        userId = handleIncomingUser(callingPid, callingUid, userId,
14041                true, false, "broadcast", callerPackage);
14042
14043        // Make sure that the user who is receiving this broadcast is started.
14044        // If not, we will just skip it.
14045
14046
14047        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14048            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14049                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14050                Slog.w(TAG, "Skipping broadcast of " + intent
14051                        + ": user " + userId + " is stopped");
14052                return ActivityManager.BROADCAST_SUCCESS;
14053            }
14054        }
14055
14056        /*
14057         * Prevent non-system code (defined here to be non-persistent
14058         * processes) from sending protected broadcasts.
14059         */
14060        int callingAppId = UserHandle.getAppId(callingUid);
14061        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14062            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14063            || callingAppId == Process.NFC_UID || callingUid == 0) {
14064            // Always okay.
14065        } else if (callerApp == null || !callerApp.persistent) {
14066            try {
14067                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14068                        intent.getAction())) {
14069                    String msg = "Permission Denial: not allowed to send broadcast "
14070                            + intent.getAction() + " from pid="
14071                            + callingPid + ", uid=" + callingUid;
14072                    Slog.w(TAG, msg);
14073                    throw new SecurityException(msg);
14074                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14075                    // Special case for compatibility: we don't want apps to send this,
14076                    // but historically it has not been protected and apps may be using it
14077                    // to poke their own app widget.  So, instead of making it protected,
14078                    // just limit it to the caller.
14079                    if (callerApp == null) {
14080                        String msg = "Permission Denial: not allowed to send broadcast "
14081                                + intent.getAction() + " from unknown caller.";
14082                        Slog.w(TAG, msg);
14083                        throw new SecurityException(msg);
14084                    } else if (intent.getComponent() != null) {
14085                        // They are good enough to send to an explicit component...  verify
14086                        // it is being sent to the calling app.
14087                        if (!intent.getComponent().getPackageName().equals(
14088                                callerApp.info.packageName)) {
14089                            String msg = "Permission Denial: not allowed to send broadcast "
14090                                    + intent.getAction() + " to "
14091                                    + intent.getComponent().getPackageName() + " from "
14092                                    + callerApp.info.packageName;
14093                            Slog.w(TAG, msg);
14094                            throw new SecurityException(msg);
14095                        }
14096                    } else {
14097                        // Limit broadcast to their own package.
14098                        intent.setPackage(callerApp.info.packageName);
14099                    }
14100                }
14101            } catch (RemoteException e) {
14102                Slog.w(TAG, "Remote exception", e);
14103                return ActivityManager.BROADCAST_SUCCESS;
14104            }
14105        }
14106
14107        // Handle special intents: if this broadcast is from the package
14108        // manager about a package being removed, we need to remove all of
14109        // its activities from the history stack.
14110        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14111                intent.getAction());
14112        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14113                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14114                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14115                || uidRemoved) {
14116            if (checkComponentPermission(
14117                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14118                    callingPid, callingUid, -1, true)
14119                    == PackageManager.PERMISSION_GRANTED) {
14120                if (uidRemoved) {
14121                    final Bundle intentExtras = intent.getExtras();
14122                    final int uid = intentExtras != null
14123                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14124                    if (uid >= 0) {
14125                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14126                        synchronized (bs) {
14127                            bs.removeUidStatsLocked(uid);
14128                        }
14129                        mAppOpsService.uidRemoved(uid);
14130                    }
14131                } else {
14132                    // If resources are unavailable just force stop all
14133                    // those packages and flush the attribute cache as well.
14134                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14135                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14136                        if (list != null && (list.length > 0)) {
14137                            for (String pkg : list) {
14138                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14139                                        "storage unmount");
14140                            }
14141                            sendPackageBroadcastLocked(
14142                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14143                        }
14144                    } else {
14145                        Uri data = intent.getData();
14146                        String ssp;
14147                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14148                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14149                                    intent.getAction());
14150                            boolean fullUninstall = removed &&
14151                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14152                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14153                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14154                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14155                                        false, fullUninstall, userId,
14156                                        removed ? "pkg removed" : "pkg changed");
14157                            }
14158                            if (removed) {
14159                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14160                                        new String[] {ssp}, userId);
14161                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14162                                    mAppOpsService.packageRemoved(
14163                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14164
14165                                    // Remove all permissions granted from/to this package
14166                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14167                                }
14168                            }
14169                        }
14170                    }
14171                }
14172            } else {
14173                String msg = "Permission Denial: " + intent.getAction()
14174                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14175                        + ", uid=" + callingUid + ")"
14176                        + " requires "
14177                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14178                Slog.w(TAG, msg);
14179                throw new SecurityException(msg);
14180            }
14181
14182        // Special case for adding a package: by default turn on compatibility
14183        // mode.
14184        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14185            Uri data = intent.getData();
14186            String ssp;
14187            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14188                mCompatModePackages.handlePackageAddedLocked(ssp,
14189                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14190            }
14191        }
14192
14193        /*
14194         * If this is the time zone changed action, queue up a message that will reset the timezone
14195         * of all currently running processes. This message will get queued up before the broadcast
14196         * happens.
14197         */
14198        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14199            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14200        }
14201
14202        /*
14203         * If the user set the time, let all running processes know.
14204         */
14205        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14206            final int is24Hour = intent.getBooleanExtra(
14207                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14208            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14209        }
14210
14211        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14212            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14213        }
14214
14215        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14216            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14217            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14218        }
14219
14220        // Add to the sticky list if requested.
14221        if (sticky) {
14222            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14223                    callingPid, callingUid)
14224                    != PackageManager.PERMISSION_GRANTED) {
14225                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14226                        + callingPid + ", uid=" + callingUid
14227                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14228                Slog.w(TAG, msg);
14229                throw new SecurityException(msg);
14230            }
14231            if (requiredPermission != null) {
14232                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14233                        + " and enforce permission " + requiredPermission);
14234                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14235            }
14236            if (intent.getComponent() != null) {
14237                throw new SecurityException(
14238                        "Sticky broadcasts can't target a specific component");
14239            }
14240            // We use userId directly here, since the "all" target is maintained
14241            // as a separate set of sticky broadcasts.
14242            if (userId != UserHandle.USER_ALL) {
14243                // But first, if this is not a broadcast to all users, then
14244                // make sure it doesn't conflict with an existing broadcast to
14245                // all users.
14246                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14247                        UserHandle.USER_ALL);
14248                if (stickies != null) {
14249                    ArrayList<Intent> list = stickies.get(intent.getAction());
14250                    if (list != null) {
14251                        int N = list.size();
14252                        int i;
14253                        for (i=0; i<N; i++) {
14254                            if (intent.filterEquals(list.get(i))) {
14255                                throw new IllegalArgumentException(
14256                                        "Sticky broadcast " + intent + " for user "
14257                                        + userId + " conflicts with existing global broadcast");
14258                            }
14259                        }
14260                    }
14261                }
14262            }
14263            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14264            if (stickies == null) {
14265                stickies = new ArrayMap<String, ArrayList<Intent>>();
14266                mStickyBroadcasts.put(userId, stickies);
14267            }
14268            ArrayList<Intent> list = stickies.get(intent.getAction());
14269            if (list == null) {
14270                list = new ArrayList<Intent>();
14271                stickies.put(intent.getAction(), list);
14272            }
14273            int N = list.size();
14274            int i;
14275            for (i=0; i<N; i++) {
14276                if (intent.filterEquals(list.get(i))) {
14277                    // This sticky already exists, replace it.
14278                    list.set(i, new Intent(intent));
14279                    break;
14280                }
14281            }
14282            if (i >= N) {
14283                list.add(new Intent(intent));
14284            }
14285        }
14286
14287        int[] users;
14288        if (userId == UserHandle.USER_ALL) {
14289            // Caller wants broadcast to go to all started users.
14290            users = mStartedUserArray;
14291        } else {
14292            // Caller wants broadcast to go to one specific user.
14293            users = new int[] {userId};
14294        }
14295
14296        // Figure out who all will receive this broadcast.
14297        List receivers = null;
14298        List<BroadcastFilter> registeredReceivers = null;
14299        // Need to resolve the intent to interested receivers...
14300        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14301                 == 0) {
14302            receivers = collectReceiverComponents(intent, resolvedType, users);
14303        }
14304        if (intent.getComponent() == null) {
14305            registeredReceivers = mReceiverResolver.queryIntent(intent,
14306                    resolvedType, false, userId);
14307        }
14308
14309        final boolean replacePending =
14310                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14311
14312        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14313                + " replacePending=" + replacePending);
14314
14315        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14316        if (!ordered && NR > 0) {
14317            // If we are not serializing this broadcast, then send the
14318            // registered receivers separately so they don't wait for the
14319            // components to be launched.
14320            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14321            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14322                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14323                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14324                    ordered, sticky, false, userId);
14325            if (DEBUG_BROADCAST) Slog.v(
14326                    TAG, "Enqueueing parallel broadcast " + r);
14327            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14328            if (!replaced) {
14329                queue.enqueueParallelBroadcastLocked(r);
14330                queue.scheduleBroadcastsLocked();
14331            }
14332            registeredReceivers = null;
14333            NR = 0;
14334        }
14335
14336        // Merge into one list.
14337        int ir = 0;
14338        if (receivers != null) {
14339            // A special case for PACKAGE_ADDED: do not allow the package
14340            // being added to see this broadcast.  This prevents them from
14341            // using this as a back door to get run as soon as they are
14342            // installed.  Maybe in the future we want to have a special install
14343            // broadcast or such for apps, but we'd like to deliberately make
14344            // this decision.
14345            String skipPackages[] = null;
14346            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14347                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14348                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14349                Uri data = intent.getData();
14350                if (data != null) {
14351                    String pkgName = data.getSchemeSpecificPart();
14352                    if (pkgName != null) {
14353                        skipPackages = new String[] { pkgName };
14354                    }
14355                }
14356            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14357                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14358            }
14359            if (skipPackages != null && (skipPackages.length > 0)) {
14360                for (String skipPackage : skipPackages) {
14361                    if (skipPackage != null) {
14362                        int NT = receivers.size();
14363                        for (int it=0; it<NT; it++) {
14364                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14365                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14366                                receivers.remove(it);
14367                                it--;
14368                                NT--;
14369                            }
14370                        }
14371                    }
14372                }
14373            }
14374
14375            int NT = receivers != null ? receivers.size() : 0;
14376            int it = 0;
14377            ResolveInfo curt = null;
14378            BroadcastFilter curr = null;
14379            while (it < NT && ir < NR) {
14380                if (curt == null) {
14381                    curt = (ResolveInfo)receivers.get(it);
14382                }
14383                if (curr == null) {
14384                    curr = registeredReceivers.get(ir);
14385                }
14386                if (curr.getPriority() >= curt.priority) {
14387                    // Insert this broadcast record into the final list.
14388                    receivers.add(it, curr);
14389                    ir++;
14390                    curr = null;
14391                    it++;
14392                    NT++;
14393                } else {
14394                    // Skip to the next ResolveInfo in the final list.
14395                    it++;
14396                    curt = null;
14397                }
14398            }
14399        }
14400        while (ir < NR) {
14401            if (receivers == null) {
14402                receivers = new ArrayList();
14403            }
14404            receivers.add(registeredReceivers.get(ir));
14405            ir++;
14406        }
14407
14408        if ((receivers != null && receivers.size() > 0)
14409                || resultTo != null) {
14410            BroadcastQueue queue = broadcastQueueForIntent(intent);
14411            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14412                    callerPackage, callingPid, callingUid, resolvedType,
14413                    requiredPermission, appOp, receivers, resultTo, resultCode,
14414                    resultData, map, ordered, sticky, false, userId);
14415            if (DEBUG_BROADCAST) Slog.v(
14416                    TAG, "Enqueueing ordered broadcast " + r
14417                    + ": prev had " + queue.mOrderedBroadcasts.size());
14418            if (DEBUG_BROADCAST) {
14419                int seq = r.intent.getIntExtra("seq", -1);
14420                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14421            }
14422            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14423            if (!replaced) {
14424                queue.enqueueOrderedBroadcastLocked(r);
14425                queue.scheduleBroadcastsLocked();
14426            }
14427        }
14428
14429        return ActivityManager.BROADCAST_SUCCESS;
14430    }
14431
14432    final Intent verifyBroadcastLocked(Intent intent) {
14433        // Refuse possible leaked file descriptors
14434        if (intent != null && intent.hasFileDescriptors() == true) {
14435            throw new IllegalArgumentException("File descriptors passed in Intent");
14436        }
14437
14438        int flags = intent.getFlags();
14439
14440        if (!mProcessesReady) {
14441            // if the caller really truly claims to know what they're doing, go
14442            // ahead and allow the broadcast without launching any receivers
14443            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14444                intent = new Intent(intent);
14445                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14446            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14447                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14448                        + " before boot completion");
14449                throw new IllegalStateException("Cannot broadcast before boot completed");
14450            }
14451        }
14452
14453        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14454            throw new IllegalArgumentException(
14455                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14456        }
14457
14458        return intent;
14459    }
14460
14461    public final int broadcastIntent(IApplicationThread caller,
14462            Intent intent, String resolvedType, IIntentReceiver resultTo,
14463            int resultCode, String resultData, Bundle map,
14464            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14465        enforceNotIsolatedCaller("broadcastIntent");
14466        synchronized(this) {
14467            intent = verifyBroadcastLocked(intent);
14468
14469            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14470            final int callingPid = Binder.getCallingPid();
14471            final int callingUid = Binder.getCallingUid();
14472            final long origId = Binder.clearCallingIdentity();
14473            int res = broadcastIntentLocked(callerApp,
14474                    callerApp != null ? callerApp.info.packageName : null,
14475                    intent, resolvedType, resultTo,
14476                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14477                    callingPid, callingUid, userId);
14478            Binder.restoreCallingIdentity(origId);
14479            return res;
14480        }
14481    }
14482
14483    int broadcastIntentInPackage(String packageName, int uid,
14484            Intent intent, String resolvedType, IIntentReceiver resultTo,
14485            int resultCode, String resultData, Bundle map,
14486            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14487        synchronized(this) {
14488            intent = verifyBroadcastLocked(intent);
14489
14490            final long origId = Binder.clearCallingIdentity();
14491            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14492                    resultTo, resultCode, resultData, map, requiredPermission,
14493                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14494            Binder.restoreCallingIdentity(origId);
14495            return res;
14496        }
14497    }
14498
14499    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14500        // Refuse possible leaked file descriptors
14501        if (intent != null && intent.hasFileDescriptors() == true) {
14502            throw new IllegalArgumentException("File descriptors passed in Intent");
14503        }
14504
14505        userId = handleIncomingUser(Binder.getCallingPid(),
14506                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14507
14508        synchronized(this) {
14509            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14510                    != PackageManager.PERMISSION_GRANTED) {
14511                String msg = "Permission Denial: unbroadcastIntent() from pid="
14512                        + Binder.getCallingPid()
14513                        + ", uid=" + Binder.getCallingUid()
14514                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14515                Slog.w(TAG, msg);
14516                throw new SecurityException(msg);
14517            }
14518            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14519            if (stickies != null) {
14520                ArrayList<Intent> list = stickies.get(intent.getAction());
14521                if (list != null) {
14522                    int N = list.size();
14523                    int i;
14524                    for (i=0; i<N; i++) {
14525                        if (intent.filterEquals(list.get(i))) {
14526                            list.remove(i);
14527                            break;
14528                        }
14529                    }
14530                    if (list.size() <= 0) {
14531                        stickies.remove(intent.getAction());
14532                    }
14533                }
14534                if (stickies.size() <= 0) {
14535                    mStickyBroadcasts.remove(userId);
14536                }
14537            }
14538        }
14539    }
14540
14541    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14542            String resultData, Bundle resultExtras, boolean resultAbort) {
14543        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14544        if (r == null) {
14545            Slog.w(TAG, "finishReceiver called but not found on queue");
14546            return false;
14547        }
14548
14549        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14550    }
14551
14552    void backgroundServicesFinishedLocked(int userId) {
14553        for (BroadcastQueue queue : mBroadcastQueues) {
14554            queue.backgroundServicesFinishedLocked(userId);
14555        }
14556    }
14557
14558    public void finishReceiver(IBinder who, int resultCode, String resultData,
14559            Bundle resultExtras, boolean resultAbort) {
14560        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14561
14562        // Refuse possible leaked file descriptors
14563        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14564            throw new IllegalArgumentException("File descriptors passed in Bundle");
14565        }
14566
14567        final long origId = Binder.clearCallingIdentity();
14568        try {
14569            boolean doNext = false;
14570            BroadcastRecord r;
14571
14572            synchronized(this) {
14573                r = broadcastRecordForReceiverLocked(who);
14574                if (r != null) {
14575                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14576                        resultData, resultExtras, resultAbort, true);
14577                }
14578            }
14579
14580            if (doNext) {
14581                r.queue.processNextBroadcast(false);
14582            }
14583            trimApplications();
14584        } finally {
14585            Binder.restoreCallingIdentity(origId);
14586        }
14587    }
14588
14589    // =========================================================
14590    // INSTRUMENTATION
14591    // =========================================================
14592
14593    public boolean startInstrumentation(ComponentName className,
14594            String profileFile, int flags, Bundle arguments,
14595            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14596            int userId, String abiOverride) {
14597        enforceNotIsolatedCaller("startInstrumentation");
14598        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14599                userId, false, true, "startInstrumentation", null);
14600        // Refuse possible leaked file descriptors
14601        if (arguments != null && arguments.hasFileDescriptors()) {
14602            throw new IllegalArgumentException("File descriptors passed in Bundle");
14603        }
14604
14605        synchronized(this) {
14606            InstrumentationInfo ii = null;
14607            ApplicationInfo ai = null;
14608            try {
14609                ii = mContext.getPackageManager().getInstrumentationInfo(
14610                    className, STOCK_PM_FLAGS);
14611                ai = AppGlobals.getPackageManager().getApplicationInfo(
14612                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14613            } catch (PackageManager.NameNotFoundException e) {
14614            } catch (RemoteException e) {
14615            }
14616            if (ii == null) {
14617                reportStartInstrumentationFailure(watcher, className,
14618                        "Unable to find instrumentation info for: " + className);
14619                return false;
14620            }
14621            if (ai == null) {
14622                reportStartInstrumentationFailure(watcher, className,
14623                        "Unable to find instrumentation target package: " + ii.targetPackage);
14624                return false;
14625            }
14626
14627            int match = mContext.getPackageManager().checkSignatures(
14628                    ii.targetPackage, ii.packageName);
14629            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14630                String msg = "Permission Denial: starting instrumentation "
14631                        + className + " from pid="
14632                        + Binder.getCallingPid()
14633                        + ", uid=" + Binder.getCallingPid()
14634                        + " not allowed because package " + ii.packageName
14635                        + " does not have a signature matching the target "
14636                        + ii.targetPackage;
14637                reportStartInstrumentationFailure(watcher, className, msg);
14638                throw new SecurityException(msg);
14639            }
14640
14641            final long origId = Binder.clearCallingIdentity();
14642            // Instrumentation can kill and relaunch even persistent processes
14643            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14644                    "start instr");
14645            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14646            app.instrumentationClass = className;
14647            app.instrumentationInfo = ai;
14648            app.instrumentationProfileFile = profileFile;
14649            app.instrumentationArguments = arguments;
14650            app.instrumentationWatcher = watcher;
14651            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14652            app.instrumentationResultClass = className;
14653            Binder.restoreCallingIdentity(origId);
14654        }
14655
14656        return true;
14657    }
14658
14659    /**
14660     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14661     * error to the logs, but if somebody is watching, send the report there too.  This enables
14662     * the "am" command to report errors with more information.
14663     *
14664     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14665     * @param cn The component name of the instrumentation.
14666     * @param report The error report.
14667     */
14668    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14669            ComponentName cn, String report) {
14670        Slog.w(TAG, report);
14671        try {
14672            if (watcher != null) {
14673                Bundle results = new Bundle();
14674                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14675                results.putString("Error", report);
14676                watcher.instrumentationStatus(cn, -1, results);
14677            }
14678        } catch (RemoteException e) {
14679            Slog.w(TAG, e);
14680        }
14681    }
14682
14683    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14684        if (app.instrumentationWatcher != null) {
14685            try {
14686                // NOTE:  IInstrumentationWatcher *must* be oneway here
14687                app.instrumentationWatcher.instrumentationFinished(
14688                    app.instrumentationClass,
14689                    resultCode,
14690                    results);
14691            } catch (RemoteException e) {
14692            }
14693        }
14694        if (app.instrumentationUiAutomationConnection != null) {
14695            try {
14696                app.instrumentationUiAutomationConnection.shutdown();
14697            } catch (RemoteException re) {
14698                /* ignore */
14699            }
14700            // Only a UiAutomation can set this flag and now that
14701            // it is finished we make sure it is reset to its default.
14702            mUserIsMonkey = false;
14703        }
14704        app.instrumentationWatcher = null;
14705        app.instrumentationUiAutomationConnection = null;
14706        app.instrumentationClass = null;
14707        app.instrumentationInfo = null;
14708        app.instrumentationProfileFile = null;
14709        app.instrumentationArguments = null;
14710
14711        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14712                "finished inst");
14713    }
14714
14715    public void finishInstrumentation(IApplicationThread target,
14716            int resultCode, Bundle results) {
14717        int userId = UserHandle.getCallingUserId();
14718        // Refuse possible leaked file descriptors
14719        if (results != null && results.hasFileDescriptors()) {
14720            throw new IllegalArgumentException("File descriptors passed in Intent");
14721        }
14722
14723        synchronized(this) {
14724            ProcessRecord app = getRecordForAppLocked(target);
14725            if (app == null) {
14726                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14727                return;
14728            }
14729            final long origId = Binder.clearCallingIdentity();
14730            finishInstrumentationLocked(app, resultCode, results);
14731            Binder.restoreCallingIdentity(origId);
14732        }
14733    }
14734
14735    // =========================================================
14736    // CONFIGURATION
14737    // =========================================================
14738
14739    public ConfigurationInfo getDeviceConfigurationInfo() {
14740        ConfigurationInfo config = new ConfigurationInfo();
14741        synchronized (this) {
14742            config.reqTouchScreen = mConfiguration.touchscreen;
14743            config.reqKeyboardType = mConfiguration.keyboard;
14744            config.reqNavigation = mConfiguration.navigation;
14745            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14746                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14747                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14748            }
14749            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14750                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14751                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14752            }
14753            config.reqGlEsVersion = GL_ES_VERSION;
14754        }
14755        return config;
14756    }
14757
14758    ActivityStack getFocusedStack() {
14759        return mStackSupervisor.getFocusedStack();
14760    }
14761
14762    public Configuration getConfiguration() {
14763        Configuration ci;
14764        synchronized(this) {
14765            ci = new Configuration(mConfiguration);
14766        }
14767        return ci;
14768    }
14769
14770    public void updatePersistentConfiguration(Configuration values) {
14771        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14772                "updateConfiguration()");
14773        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14774                "updateConfiguration()");
14775        if (values == null) {
14776            throw new NullPointerException("Configuration must not be null");
14777        }
14778
14779        synchronized(this) {
14780            final long origId = Binder.clearCallingIdentity();
14781            updateConfigurationLocked(values, null, true, false);
14782            Binder.restoreCallingIdentity(origId);
14783        }
14784    }
14785
14786    public void updateConfiguration(Configuration values) {
14787        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14788                "updateConfiguration()");
14789
14790        synchronized(this) {
14791            if (values == null && mWindowManager != null) {
14792                // sentinel: fetch the current configuration from the window manager
14793                values = mWindowManager.computeNewConfiguration();
14794            }
14795
14796            if (mWindowManager != null) {
14797                mProcessList.applyDisplaySize(mWindowManager);
14798            }
14799
14800            final long origId = Binder.clearCallingIdentity();
14801            if (values != null) {
14802                Settings.System.clearConfiguration(values);
14803            }
14804            updateConfigurationLocked(values, null, false, false);
14805            Binder.restoreCallingIdentity(origId);
14806        }
14807    }
14808
14809    /**
14810     * Do either or both things: (1) change the current configuration, and (2)
14811     * make sure the given activity is running with the (now) current
14812     * configuration.  Returns true if the activity has been left running, or
14813     * false if <var>starting</var> is being destroyed to match the new
14814     * configuration.
14815     * @param persistent TODO
14816     */
14817    boolean updateConfigurationLocked(Configuration values,
14818            ActivityRecord starting, boolean persistent, boolean initLocale) {
14819        int changes = 0;
14820
14821        if (values != null) {
14822            Configuration newConfig = new Configuration(mConfiguration);
14823            changes = newConfig.updateFrom(values);
14824            if (changes != 0) {
14825                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14826                    Slog.i(TAG, "Updating configuration to: " + values);
14827                }
14828
14829                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14830
14831                if (values.locale != null && !initLocale) {
14832                    saveLocaleLocked(values.locale,
14833                                     !values.locale.equals(mConfiguration.locale),
14834                                     values.userSetLocale);
14835                }
14836
14837                mConfigurationSeq++;
14838                if (mConfigurationSeq <= 0) {
14839                    mConfigurationSeq = 1;
14840                }
14841                newConfig.seq = mConfigurationSeq;
14842                mConfiguration = newConfig;
14843                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14844                mUsageStatsService.noteStartConfig(newConfig);
14845
14846                final Configuration configCopy = new Configuration(mConfiguration);
14847
14848                // TODO: If our config changes, should we auto dismiss any currently
14849                // showing dialogs?
14850                mShowDialogs = shouldShowDialogs(newConfig);
14851
14852                AttributeCache ac = AttributeCache.instance();
14853                if (ac != null) {
14854                    ac.updateConfiguration(configCopy);
14855                }
14856
14857                // Make sure all resources in our process are updated
14858                // right now, so that anyone who is going to retrieve
14859                // resource values after we return will be sure to get
14860                // the new ones.  This is especially important during
14861                // boot, where the first config change needs to guarantee
14862                // all resources have that config before following boot
14863                // code is executed.
14864                mSystemThread.applyConfigurationToResources(configCopy);
14865
14866                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14867                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14868                    msg.obj = new Configuration(configCopy);
14869                    mHandler.sendMessage(msg);
14870                }
14871
14872                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14873                    ProcessRecord app = mLruProcesses.get(i);
14874                    try {
14875                        if (app.thread != null) {
14876                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14877                                    + app.processName + " new config " + mConfiguration);
14878                            app.thread.scheduleConfigurationChanged(configCopy);
14879                        }
14880                    } catch (Exception e) {
14881                    }
14882                }
14883                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14884                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14885                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14886                        | Intent.FLAG_RECEIVER_FOREGROUND);
14887                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14888                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14889                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14890                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14891                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14892                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14893                    broadcastIntentLocked(null, null, intent,
14894                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14895                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14896                }
14897            }
14898        }
14899
14900        boolean kept = true;
14901        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14902        // mainStack is null during startup.
14903        if (mainStack != null) {
14904            if (changes != 0 && starting == null) {
14905                // If the configuration changed, and the caller is not already
14906                // in the process of starting an activity, then find the top
14907                // activity to check if its configuration needs to change.
14908                starting = mainStack.topRunningActivityLocked(null);
14909            }
14910
14911            if (starting != null) {
14912                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14913                // And we need to make sure at this point that all other activities
14914                // are made visible with the correct configuration.
14915                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14916            }
14917        }
14918
14919        if (values != null && mWindowManager != null) {
14920            mWindowManager.setNewConfiguration(mConfiguration);
14921        }
14922
14923        return kept;
14924    }
14925
14926    /**
14927     * Decide based on the configuration whether we should shouw the ANR,
14928     * crash, etc dialogs.  The idea is that if there is no affordnace to
14929     * press the on-screen buttons, we shouldn't show the dialog.
14930     *
14931     * A thought: SystemUI might also want to get told about this, the Power
14932     * dialog / global actions also might want different behaviors.
14933     */
14934    private static final boolean shouldShowDialogs(Configuration config) {
14935        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14936                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14937    }
14938
14939    /**
14940     * Save the locale.  You must be inside a synchronized (this) block.
14941     */
14942    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14943        if(isDiff) {
14944            SystemProperties.set("user.language", l.getLanguage());
14945            SystemProperties.set("user.region", l.getCountry());
14946        }
14947
14948        if(isPersist) {
14949            SystemProperties.set("persist.sys.language", l.getLanguage());
14950            SystemProperties.set("persist.sys.country", l.getCountry());
14951            SystemProperties.set("persist.sys.localevar", l.getVariant());
14952        }
14953    }
14954
14955    @Override
14956    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14957        ActivityRecord srec = ActivityRecord.forToken(token);
14958        return srec != null && srec.task.affinity != null &&
14959                srec.task.affinity.equals(destAffinity);
14960    }
14961
14962    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14963            Intent resultData) {
14964
14965        synchronized (this) {
14966            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14967            if (stack != null) {
14968                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14969            }
14970            return false;
14971        }
14972    }
14973
14974    public int getLaunchedFromUid(IBinder activityToken) {
14975        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14976        if (srec == null) {
14977            return -1;
14978        }
14979        return srec.launchedFromUid;
14980    }
14981
14982    public String getLaunchedFromPackage(IBinder activityToken) {
14983        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14984        if (srec == null) {
14985            return null;
14986        }
14987        return srec.launchedFromPackage;
14988    }
14989
14990    // =========================================================
14991    // LIFETIME MANAGEMENT
14992    // =========================================================
14993
14994    // Returns which broadcast queue the app is the current [or imminent] receiver
14995    // on, or 'null' if the app is not an active broadcast recipient.
14996    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14997        BroadcastRecord r = app.curReceiver;
14998        if (r != null) {
14999            return r.queue;
15000        }
15001
15002        // It's not the current receiver, but it might be starting up to become one
15003        synchronized (this) {
15004            for (BroadcastQueue queue : mBroadcastQueues) {
15005                r = queue.mPendingBroadcast;
15006                if (r != null && r.curApp == app) {
15007                    // found it; report which queue it's in
15008                    return queue;
15009                }
15010            }
15011        }
15012
15013        return null;
15014    }
15015
15016    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15017            boolean doingAll, long now) {
15018        if (mAdjSeq == app.adjSeq) {
15019            // This adjustment has already been computed.
15020            return app.curRawAdj;
15021        }
15022
15023        if (app.thread == null) {
15024            app.adjSeq = mAdjSeq;
15025            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15026            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15027            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15028        }
15029
15030        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15031        app.adjSource = null;
15032        app.adjTarget = null;
15033        app.empty = false;
15034        app.cached = false;
15035
15036        final int activitiesSize = app.activities.size();
15037
15038        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15039            // The max adjustment doesn't allow this app to be anything
15040            // below foreground, so it is not worth doing work for it.
15041            app.adjType = "fixed";
15042            app.adjSeq = mAdjSeq;
15043            app.curRawAdj = app.maxAdj;
15044            app.foregroundActivities = false;
15045            app.keeping = true;
15046            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15047            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15048            // System processes can do UI, and when they do we want to have
15049            // them trim their memory after the user leaves the UI.  To
15050            // facilitate this, here we need to determine whether or not it
15051            // is currently showing UI.
15052            app.systemNoUi = true;
15053            if (app == TOP_APP) {
15054                app.systemNoUi = false;
15055            } else if (activitiesSize > 0) {
15056                for (int j = 0; j < activitiesSize; j++) {
15057                    final ActivityRecord r = app.activities.get(j);
15058                    if (r.visible) {
15059                        app.systemNoUi = false;
15060                    }
15061                }
15062            }
15063            if (!app.systemNoUi) {
15064                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15065            }
15066            return (app.curAdj=app.maxAdj);
15067        }
15068
15069        app.keeping = false;
15070        app.systemNoUi = false;
15071
15072        // Determine the importance of the process, starting with most
15073        // important to least, and assign an appropriate OOM adjustment.
15074        int adj;
15075        int schedGroup;
15076        int procState;
15077        boolean foregroundActivities = false;
15078        BroadcastQueue queue;
15079        if (app == TOP_APP) {
15080            // The last app on the list is the foreground app.
15081            adj = ProcessList.FOREGROUND_APP_ADJ;
15082            schedGroup = Process.THREAD_GROUP_DEFAULT;
15083            app.adjType = "top-activity";
15084            foregroundActivities = true;
15085            procState = ActivityManager.PROCESS_STATE_TOP;
15086        } else if (app.instrumentationClass != null) {
15087            // Don't want to kill running instrumentation.
15088            adj = ProcessList.FOREGROUND_APP_ADJ;
15089            schedGroup = Process.THREAD_GROUP_DEFAULT;
15090            app.adjType = "instrumentation";
15091            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15092        } else if ((queue = isReceivingBroadcast(app)) != null) {
15093            // An app that is currently receiving a broadcast also
15094            // counts as being in the foreground for OOM killer purposes.
15095            // It's placed in a sched group based on the nature of the
15096            // broadcast as reflected by which queue it's active in.
15097            adj = ProcessList.FOREGROUND_APP_ADJ;
15098            schedGroup = (queue == mFgBroadcastQueue)
15099                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15100            app.adjType = "broadcast";
15101            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15102        } else if (app.executingServices.size() > 0) {
15103            // An app that is currently executing a service callback also
15104            // counts as being in the foreground.
15105            adj = ProcessList.FOREGROUND_APP_ADJ;
15106            schedGroup = app.execServicesFg ?
15107                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15108            app.adjType = "exec-service";
15109            procState = ActivityManager.PROCESS_STATE_SERVICE;
15110            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15111        } else {
15112            // As far as we know the process is empty.  We may change our mind later.
15113            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15114            // At this point we don't actually know the adjustment.  Use the cached adj
15115            // value that the caller wants us to.
15116            adj = cachedAdj;
15117            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15118            app.cached = true;
15119            app.empty = true;
15120            app.adjType = "cch-empty";
15121        }
15122
15123        // Examine all activities if not already foreground.
15124        if (!foregroundActivities && activitiesSize > 0) {
15125            for (int j = 0; j < activitiesSize; j++) {
15126                final ActivityRecord r = app.activities.get(j);
15127                if (r.app != app) {
15128                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15129                            + app + "?!?");
15130                    continue;
15131                }
15132                if (r.visible) {
15133                    // App has a visible activity; only upgrade adjustment.
15134                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15135                        adj = ProcessList.VISIBLE_APP_ADJ;
15136                        app.adjType = "visible";
15137                    }
15138                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15139                        procState = ActivityManager.PROCESS_STATE_TOP;
15140                    }
15141                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15142                    app.cached = false;
15143                    app.empty = false;
15144                    foregroundActivities = true;
15145                    break;
15146                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15147                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15148                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15149                        app.adjType = "pausing";
15150                    }
15151                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15152                        procState = ActivityManager.PROCESS_STATE_TOP;
15153                    }
15154                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15155                    app.cached = false;
15156                    app.empty = false;
15157                    foregroundActivities = true;
15158                } else if (r.state == ActivityState.STOPPING) {
15159                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15160                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15161                        app.adjType = "stopping";
15162                    }
15163                    // For the process state, we will at this point consider the
15164                    // process to be cached.  It will be cached either as an activity
15165                    // or empty depending on whether the activity is finishing.  We do
15166                    // this so that we can treat the process as cached for purposes of
15167                    // memory trimming (determing current memory level, trim command to
15168                    // send to process) since there can be an arbitrary number of stopping
15169                    // processes and they should soon all go into the cached state.
15170                    if (!r.finishing) {
15171                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15172                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15173                        }
15174                    }
15175                    app.cached = false;
15176                    app.empty = false;
15177                    foregroundActivities = true;
15178                } else {
15179                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15180                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15181                        app.adjType = "cch-act";
15182                    }
15183                }
15184            }
15185        }
15186
15187        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15188            if (app.foregroundServices) {
15189                // The user is aware of this app, so make it visible.
15190                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15191                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15192                app.cached = false;
15193                app.adjType = "fg-service";
15194                schedGroup = Process.THREAD_GROUP_DEFAULT;
15195            } else if (app.forcingToForeground != null) {
15196                // The user is aware of this app, so make it visible.
15197                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15198                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15199                app.cached = false;
15200                app.adjType = "force-fg";
15201                app.adjSource = app.forcingToForeground;
15202                schedGroup = Process.THREAD_GROUP_DEFAULT;
15203            }
15204        }
15205
15206        if (app == mHeavyWeightProcess) {
15207            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15208                // We don't want to kill the current heavy-weight process.
15209                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15210                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15211                app.cached = false;
15212                app.adjType = "heavy";
15213            }
15214            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15215                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15216            }
15217        }
15218
15219        if (app == mHomeProcess) {
15220            if (adj > ProcessList.HOME_APP_ADJ) {
15221                // This process is hosting what we currently consider to be the
15222                // home app, so we don't want to let it go into the background.
15223                adj = ProcessList.HOME_APP_ADJ;
15224                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15225                app.cached = false;
15226                app.adjType = "home";
15227            }
15228            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15229                procState = ActivityManager.PROCESS_STATE_HOME;
15230            }
15231        }
15232
15233        if (app == mPreviousProcess && app.activities.size() > 0) {
15234            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15235                // This was the previous process that showed UI to the user.
15236                // We want to try to keep it around more aggressively, to give
15237                // a good experience around switching between two apps.
15238                adj = ProcessList.PREVIOUS_APP_ADJ;
15239                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15240                app.cached = false;
15241                app.adjType = "previous";
15242            }
15243            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15244                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15245            }
15246        }
15247
15248        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15249                + " reason=" + app.adjType);
15250
15251        // By default, we use the computed adjustment.  It may be changed if
15252        // there are applications dependent on our services or providers, but
15253        // this gives us a baseline and makes sure we don't get into an
15254        // infinite recursion.
15255        app.adjSeq = mAdjSeq;
15256        app.curRawAdj = adj;
15257        app.hasStartedServices = false;
15258
15259        if (mBackupTarget != null && app == mBackupTarget.app) {
15260            // If possible we want to avoid killing apps while they're being backed up
15261            if (adj > ProcessList.BACKUP_APP_ADJ) {
15262                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15263                adj = ProcessList.BACKUP_APP_ADJ;
15264                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15265                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15266                }
15267                app.adjType = "backup";
15268                app.cached = false;
15269            }
15270            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15271                procState = ActivityManager.PROCESS_STATE_BACKUP;
15272            }
15273        }
15274
15275        boolean mayBeTop = false;
15276
15277        for (int is = app.services.size()-1;
15278                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15279                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15280                        || procState > ActivityManager.PROCESS_STATE_TOP);
15281                is--) {
15282            ServiceRecord s = app.services.valueAt(is);
15283            if (s.startRequested) {
15284                app.hasStartedServices = true;
15285                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15286                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15287                }
15288                if (app.hasShownUi && app != mHomeProcess) {
15289                    // If this process has shown some UI, let it immediately
15290                    // go to the LRU list because it may be pretty heavy with
15291                    // UI stuff.  We'll tag it with a label just to help
15292                    // debug and understand what is going on.
15293                    if (adj > ProcessList.SERVICE_ADJ) {
15294                        app.adjType = "cch-started-ui-services";
15295                    }
15296                } else {
15297                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15298                        // This service has seen some activity within
15299                        // recent memory, so we will keep its process ahead
15300                        // of the background processes.
15301                        if (adj > ProcessList.SERVICE_ADJ) {
15302                            adj = ProcessList.SERVICE_ADJ;
15303                            app.adjType = "started-services";
15304                            app.cached = false;
15305                        }
15306                    }
15307                    // If we have let the service slide into the background
15308                    // state, still have some text describing what it is doing
15309                    // even though the service no longer has an impact.
15310                    if (adj > ProcessList.SERVICE_ADJ) {
15311                        app.adjType = "cch-started-services";
15312                    }
15313                }
15314                // Don't kill this process because it is doing work; it
15315                // has said it is doing work.
15316                app.keeping = true;
15317            }
15318            for (int conni = s.connections.size()-1;
15319                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15320                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15321                            || procState > ActivityManager.PROCESS_STATE_TOP);
15322                    conni--) {
15323                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15324                for (int i = 0;
15325                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15326                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15327                                || procState > ActivityManager.PROCESS_STATE_TOP);
15328                        i++) {
15329                    // XXX should compute this based on the max of
15330                    // all connected clients.
15331                    ConnectionRecord cr = clist.get(i);
15332                    if (cr.binding.client == app) {
15333                        // Binding to ourself is not interesting.
15334                        continue;
15335                    }
15336                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15337                        ProcessRecord client = cr.binding.client;
15338                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15339                                TOP_APP, doingAll, now);
15340                        int clientProcState = client.curProcState;
15341                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15342                            // If the other app is cached for any reason, for purposes here
15343                            // we are going to consider it empty.  The specific cached state
15344                            // doesn't propagate except under certain conditions.
15345                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15346                        }
15347                        String adjType = null;
15348                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15349                            // Not doing bind OOM management, so treat
15350                            // this guy more like a started service.
15351                            if (app.hasShownUi && app != mHomeProcess) {
15352                                // If this process has shown some UI, let it immediately
15353                                // go to the LRU list because it may be pretty heavy with
15354                                // UI stuff.  We'll tag it with a label just to help
15355                                // debug and understand what is going on.
15356                                if (adj > clientAdj) {
15357                                    adjType = "cch-bound-ui-services";
15358                                }
15359                                app.cached = false;
15360                                clientAdj = adj;
15361                                clientProcState = procState;
15362                            } else {
15363                                if (now >= (s.lastActivity
15364                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15365                                    // This service has not seen activity within
15366                                    // recent memory, so allow it to drop to the
15367                                    // LRU list if there is no other reason to keep
15368                                    // it around.  We'll also tag it with a label just
15369                                    // to help debug and undertand what is going on.
15370                                    if (adj > clientAdj) {
15371                                        adjType = "cch-bound-services";
15372                                    }
15373                                    clientAdj = adj;
15374                                }
15375                            }
15376                        }
15377                        if (adj > clientAdj) {
15378                            // If this process has recently shown UI, and
15379                            // the process that is binding to it is less
15380                            // important than being visible, then we don't
15381                            // care about the binding as much as we care
15382                            // about letting this process get into the LRU
15383                            // list to be killed and restarted if needed for
15384                            // memory.
15385                            if (app.hasShownUi && app != mHomeProcess
15386                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15387                                adjType = "cch-bound-ui-services";
15388                            } else {
15389                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15390                                        |Context.BIND_IMPORTANT)) != 0) {
15391                                    adj = clientAdj;
15392                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15393                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15394                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15395                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15396                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15397                                    adj = clientAdj;
15398                                } else {
15399                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15400                                        adj = ProcessList.VISIBLE_APP_ADJ;
15401                                    }
15402                                }
15403                                if (!client.cached) {
15404                                    app.cached = false;
15405                                }
15406                                if (client.keeping) {
15407                                    app.keeping = true;
15408                                }
15409                                adjType = "service";
15410                            }
15411                        }
15412                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15413                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15414                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15415                            }
15416                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15417                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15418                                    // Special handling of clients who are in the top state.
15419                                    // We *may* want to consider this process to be in the
15420                                    // top state as well, but only if there is not another
15421                                    // reason for it to be running.  Being on the top is a
15422                                    // special state, meaning you are specifically running
15423                                    // for the current top app.  If the process is already
15424                                    // running in the background for some other reason, it
15425                                    // is more important to continue considering it to be
15426                                    // in the background state.
15427                                    mayBeTop = true;
15428                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15429                                } else {
15430                                    // Special handling for above-top states (persistent
15431                                    // processes).  These should not bring the current process
15432                                    // into the top state, since they are not on top.  Instead
15433                                    // give them the best state after that.
15434                                    clientProcState =
15435                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15436                                }
15437                            }
15438                        } else {
15439                            if (clientProcState <
15440                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15441                                clientProcState =
15442                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15443                            }
15444                        }
15445                        if (procState > clientProcState) {
15446                            procState = clientProcState;
15447                        }
15448                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15449                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15450                            app.pendingUiClean = true;
15451                        }
15452                        if (adjType != null) {
15453                            app.adjType = adjType;
15454                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15455                                    .REASON_SERVICE_IN_USE;
15456                            app.adjSource = cr.binding.client;
15457                            app.adjSourceOom = clientAdj;
15458                            app.adjTarget = s.name;
15459                        }
15460                    }
15461                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15462                        app.treatLikeActivity = true;
15463                    }
15464                    final ActivityRecord a = cr.activity;
15465                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15466                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15467                                (a.visible || a.state == ActivityState.RESUMED
15468                                 || a.state == ActivityState.PAUSING)) {
15469                            adj = ProcessList.FOREGROUND_APP_ADJ;
15470                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15471                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15472                            }
15473                            app.cached = false;
15474                            app.adjType = "service";
15475                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15476                                    .REASON_SERVICE_IN_USE;
15477                            app.adjSource = a;
15478                            app.adjSourceOom = adj;
15479                            app.adjTarget = s.name;
15480                        }
15481                    }
15482                }
15483            }
15484        }
15485
15486        for (int provi = app.pubProviders.size()-1;
15487                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15488                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15489                        || procState > ActivityManager.PROCESS_STATE_TOP);
15490                provi--) {
15491            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15492            for (int i = cpr.connections.size()-1;
15493                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15494                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15495                            || procState > ActivityManager.PROCESS_STATE_TOP);
15496                    i--) {
15497                ContentProviderConnection conn = cpr.connections.get(i);
15498                ProcessRecord client = conn.client;
15499                if (client == app) {
15500                    // Being our own client is not interesting.
15501                    continue;
15502                }
15503                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15504                int clientProcState = client.curProcState;
15505                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15506                    // If the other app is cached for any reason, for purposes here
15507                    // we are going to consider it empty.
15508                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15509                }
15510                if (adj > clientAdj) {
15511                    if (app.hasShownUi && app != mHomeProcess
15512                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15513                        app.adjType = "cch-ui-provider";
15514                    } else {
15515                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15516                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15517                        app.adjType = "provider";
15518                    }
15519                    app.cached &= client.cached;
15520                    app.keeping |= client.keeping;
15521                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15522                            .REASON_PROVIDER_IN_USE;
15523                    app.adjSource = client;
15524                    app.adjSourceOom = clientAdj;
15525                    app.adjTarget = cpr.name;
15526                }
15527                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15528                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15529                        // Special handling of clients who are in the top state.
15530                        // We *may* want to consider this process to be in the
15531                        // top state as well, but only if there is not another
15532                        // reason for it to be running.  Being on the top is a
15533                        // special state, meaning you are specifically running
15534                        // for the current top app.  If the process is already
15535                        // running in the background for some other reason, it
15536                        // is more important to continue considering it to be
15537                        // in the background state.
15538                        mayBeTop = true;
15539                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15540                    } else {
15541                        // Special handling for above-top states (persistent
15542                        // processes).  These should not bring the current process
15543                        // into the top state, since they are not on top.  Instead
15544                        // give them the best state after that.
15545                        clientProcState =
15546                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15547                    }
15548                }
15549                if (procState > clientProcState) {
15550                    procState = clientProcState;
15551                }
15552                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15553                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15554                }
15555            }
15556            // If the provider has external (non-framework) process
15557            // dependencies, ensure that its adjustment is at least
15558            // FOREGROUND_APP_ADJ.
15559            if (cpr.hasExternalProcessHandles()) {
15560                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15561                    adj = ProcessList.FOREGROUND_APP_ADJ;
15562                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15563                    app.cached = false;
15564                    app.keeping = true;
15565                    app.adjType = "provider";
15566                    app.adjTarget = cpr.name;
15567                }
15568                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15569                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15570                }
15571            }
15572        }
15573
15574        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15575            // A client of one of our services or providers is in the top state.  We
15576            // *may* want to be in the top state, but not if we are already running in
15577            // the background for some other reason.  For the decision here, we are going
15578            // to pick out a few specific states that we want to remain in when a client
15579            // is top (states that tend to be longer-term) and otherwise allow it to go
15580            // to the top state.
15581            switch (procState) {
15582                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15583                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15584                case ActivityManager.PROCESS_STATE_SERVICE:
15585                    // These all are longer-term states, so pull them up to the top
15586                    // of the background states, but not all the way to the top state.
15587                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15588                    break;
15589                default:
15590                    // Otherwise, top is a better choice, so take it.
15591                    procState = ActivityManager.PROCESS_STATE_TOP;
15592                    break;
15593            }
15594        }
15595
15596        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15597            if (app.hasClientActivities) {
15598                // This is a cached process, but with client activities.  Mark it so.
15599                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15600                app.adjType = "cch-client-act";
15601            } else if (app.treatLikeActivity) {
15602                // This is a cached process, but somebody wants us to treat it like it has
15603                // an activity, okay!
15604                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15605                app.adjType = "cch-as-act";
15606            }
15607        }
15608
15609        if (adj == ProcessList.SERVICE_ADJ) {
15610            if (doingAll) {
15611                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15612                mNewNumServiceProcs++;
15613                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15614                if (!app.serviceb) {
15615                    // This service isn't far enough down on the LRU list to
15616                    // normally be a B service, but if we are low on RAM and it
15617                    // is large we want to force it down since we would prefer to
15618                    // keep launcher over it.
15619                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15620                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15621                        app.serviceHighRam = true;
15622                        app.serviceb = true;
15623                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15624                    } else {
15625                        mNewNumAServiceProcs++;
15626                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15627                    }
15628                } else {
15629                    app.serviceHighRam = false;
15630                }
15631            }
15632            if (app.serviceb) {
15633                adj = ProcessList.SERVICE_B_ADJ;
15634            }
15635        }
15636
15637        app.curRawAdj = adj;
15638
15639        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15640        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15641        if (adj > app.maxAdj) {
15642            adj = app.maxAdj;
15643            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15644                schedGroup = Process.THREAD_GROUP_DEFAULT;
15645            }
15646        }
15647        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15648            app.keeping = true;
15649        }
15650
15651        // Do final modification to adj.  Everything we do between here and applying
15652        // the final setAdj must be done in this function, because we will also use
15653        // it when computing the final cached adj later.  Note that we don't need to
15654        // worry about this for max adj above, since max adj will always be used to
15655        // keep it out of the cached vaues.
15656        app.curAdj = app.modifyRawOomAdj(adj);
15657        app.curSchedGroup = schedGroup;
15658        app.curProcState = procState;
15659        app.foregroundActivities = foregroundActivities;
15660
15661        return app.curRawAdj;
15662    }
15663
15664    /**
15665     * Schedule PSS collection of a process.
15666     */
15667    void requestPssLocked(ProcessRecord proc, int procState) {
15668        if (mPendingPssProcesses.contains(proc)) {
15669            return;
15670        }
15671        if (mPendingPssProcesses.size() == 0) {
15672            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15673        }
15674        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15675        proc.pssProcState = procState;
15676        mPendingPssProcesses.add(proc);
15677    }
15678
15679    /**
15680     * Schedule PSS collection of all processes.
15681     */
15682    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15683        if (!always) {
15684            if (now < (mLastFullPssTime +
15685                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15686                return;
15687            }
15688        }
15689        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15690        mLastFullPssTime = now;
15691        mFullPssPending = true;
15692        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15693        mPendingPssProcesses.clear();
15694        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15695            ProcessRecord app = mLruProcesses.get(i);
15696            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15697                app.pssProcState = app.setProcState;
15698                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15699                        isSleeping(), now);
15700                mPendingPssProcesses.add(app);
15701            }
15702        }
15703        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15704    }
15705
15706    /**
15707     * Ask a given process to GC right now.
15708     */
15709    final void performAppGcLocked(ProcessRecord app) {
15710        try {
15711            app.lastRequestedGc = SystemClock.uptimeMillis();
15712            if (app.thread != null) {
15713                if (app.reportLowMemory) {
15714                    app.reportLowMemory = false;
15715                    app.thread.scheduleLowMemory();
15716                } else {
15717                    app.thread.processInBackground();
15718                }
15719            }
15720        } catch (Exception e) {
15721            // whatever.
15722        }
15723    }
15724
15725    /**
15726     * Returns true if things are idle enough to perform GCs.
15727     */
15728    private final boolean canGcNowLocked() {
15729        boolean processingBroadcasts = false;
15730        for (BroadcastQueue q : mBroadcastQueues) {
15731            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15732                processingBroadcasts = true;
15733            }
15734        }
15735        return !processingBroadcasts
15736                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15737    }
15738
15739    /**
15740     * Perform GCs on all processes that are waiting for it, but only
15741     * if things are idle.
15742     */
15743    final void performAppGcsLocked() {
15744        final int N = mProcessesToGc.size();
15745        if (N <= 0) {
15746            return;
15747        }
15748        if (canGcNowLocked()) {
15749            while (mProcessesToGc.size() > 0) {
15750                ProcessRecord proc = mProcessesToGc.remove(0);
15751                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15752                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15753                            <= SystemClock.uptimeMillis()) {
15754                        // To avoid spamming the system, we will GC processes one
15755                        // at a time, waiting a few seconds between each.
15756                        performAppGcLocked(proc);
15757                        scheduleAppGcsLocked();
15758                        return;
15759                    } else {
15760                        // It hasn't been long enough since we last GCed this
15761                        // process...  put it in the list to wait for its time.
15762                        addProcessToGcListLocked(proc);
15763                        break;
15764                    }
15765                }
15766            }
15767
15768            scheduleAppGcsLocked();
15769        }
15770    }
15771
15772    /**
15773     * If all looks good, perform GCs on all processes waiting for them.
15774     */
15775    final void performAppGcsIfAppropriateLocked() {
15776        if (canGcNowLocked()) {
15777            performAppGcsLocked();
15778            return;
15779        }
15780        // Still not idle, wait some more.
15781        scheduleAppGcsLocked();
15782    }
15783
15784    /**
15785     * Schedule the execution of all pending app GCs.
15786     */
15787    final void scheduleAppGcsLocked() {
15788        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15789
15790        if (mProcessesToGc.size() > 0) {
15791            // Schedule a GC for the time to the next process.
15792            ProcessRecord proc = mProcessesToGc.get(0);
15793            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15794
15795            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15796            long now = SystemClock.uptimeMillis();
15797            if (when < (now+GC_TIMEOUT)) {
15798                when = now + GC_TIMEOUT;
15799            }
15800            mHandler.sendMessageAtTime(msg, when);
15801        }
15802    }
15803
15804    /**
15805     * Add a process to the array of processes waiting to be GCed.  Keeps the
15806     * list in sorted order by the last GC time.  The process can't already be
15807     * on the list.
15808     */
15809    final void addProcessToGcListLocked(ProcessRecord proc) {
15810        boolean added = false;
15811        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15812            if (mProcessesToGc.get(i).lastRequestedGc <
15813                    proc.lastRequestedGc) {
15814                added = true;
15815                mProcessesToGc.add(i+1, proc);
15816                break;
15817            }
15818        }
15819        if (!added) {
15820            mProcessesToGc.add(0, proc);
15821        }
15822    }
15823
15824    /**
15825     * Set up to ask a process to GC itself.  This will either do it
15826     * immediately, or put it on the list of processes to gc the next
15827     * time things are idle.
15828     */
15829    final void scheduleAppGcLocked(ProcessRecord app) {
15830        long now = SystemClock.uptimeMillis();
15831        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15832            return;
15833        }
15834        if (!mProcessesToGc.contains(app)) {
15835            addProcessToGcListLocked(app);
15836            scheduleAppGcsLocked();
15837        }
15838    }
15839
15840    final void checkExcessivePowerUsageLocked(boolean doKills) {
15841        updateCpuStatsNow();
15842
15843        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15844        boolean doWakeKills = doKills;
15845        boolean doCpuKills = doKills;
15846        if (mLastPowerCheckRealtime == 0) {
15847            doWakeKills = false;
15848        }
15849        if (mLastPowerCheckUptime == 0) {
15850            doCpuKills = false;
15851        }
15852        if (stats.isScreenOn()) {
15853            doWakeKills = false;
15854        }
15855        final long curRealtime = SystemClock.elapsedRealtime();
15856        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15857        final long curUptime = SystemClock.uptimeMillis();
15858        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15859        mLastPowerCheckRealtime = curRealtime;
15860        mLastPowerCheckUptime = curUptime;
15861        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15862            doWakeKills = false;
15863        }
15864        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15865            doCpuKills = false;
15866        }
15867        int i = mLruProcesses.size();
15868        while (i > 0) {
15869            i--;
15870            ProcessRecord app = mLruProcesses.get(i);
15871            if (!app.keeping) {
15872                long wtime;
15873                synchronized (stats) {
15874                    wtime = stats.getProcessWakeTime(app.info.uid,
15875                            app.pid, curRealtime);
15876                }
15877                long wtimeUsed = wtime - app.lastWakeTime;
15878                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15879                if (DEBUG_POWER) {
15880                    StringBuilder sb = new StringBuilder(128);
15881                    sb.append("Wake for ");
15882                    app.toShortString(sb);
15883                    sb.append(": over ");
15884                    TimeUtils.formatDuration(realtimeSince, sb);
15885                    sb.append(" used ");
15886                    TimeUtils.formatDuration(wtimeUsed, sb);
15887                    sb.append(" (");
15888                    sb.append((wtimeUsed*100)/realtimeSince);
15889                    sb.append("%)");
15890                    Slog.i(TAG, sb.toString());
15891                    sb.setLength(0);
15892                    sb.append("CPU for ");
15893                    app.toShortString(sb);
15894                    sb.append(": over ");
15895                    TimeUtils.formatDuration(uptimeSince, sb);
15896                    sb.append(" used ");
15897                    TimeUtils.formatDuration(cputimeUsed, sb);
15898                    sb.append(" (");
15899                    sb.append((cputimeUsed*100)/uptimeSince);
15900                    sb.append("%)");
15901                    Slog.i(TAG, sb.toString());
15902                }
15903                // If a process has held a wake lock for more
15904                // than 50% of the time during this period,
15905                // that sounds bad.  Kill!
15906                if (doWakeKills && realtimeSince > 0
15907                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15908                    synchronized (stats) {
15909                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15910                                realtimeSince, wtimeUsed);
15911                    }
15912                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15913                            + " during " + realtimeSince);
15914                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15915                } else if (doCpuKills && uptimeSince > 0
15916                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15917                    synchronized (stats) {
15918                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15919                                uptimeSince, cputimeUsed);
15920                    }
15921                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15922                            + " during " + uptimeSince);
15923                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15924                } else {
15925                    app.lastWakeTime = wtime;
15926                    app.lastCpuTime = app.curCpuTime;
15927                }
15928            }
15929        }
15930    }
15931
15932    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15933            ProcessRecord TOP_APP, boolean doingAll, long now) {
15934        boolean success = true;
15935
15936        if (app.curRawAdj != app.setRawAdj) {
15937            if (wasKeeping && !app.keeping) {
15938                // This app is no longer something we want to keep.  Note
15939                // its current wake lock time to later know to kill it if
15940                // it is not behaving well.
15941                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15942                synchronized (stats) {
15943                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15944                            app.pid, SystemClock.elapsedRealtime());
15945                }
15946                app.lastCpuTime = app.curCpuTime;
15947            }
15948
15949            app.setRawAdj = app.curRawAdj;
15950        }
15951
15952        int changes = 0;
15953
15954        if (app.curAdj != app.setAdj) {
15955            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
15956            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15957                TAG, "Set " + app.pid + " " + app.processName +
15958                " adj " + app.curAdj + ": " + app.adjType);
15959            app.setAdj = app.curAdj;
15960        }
15961
15962        if (app.setSchedGroup != app.curSchedGroup) {
15963            app.setSchedGroup = app.curSchedGroup;
15964            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15965                    "Setting process group of " + app.processName
15966                    + " to " + app.curSchedGroup);
15967            if (app.waitingToKill != null &&
15968                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15969                killUnneededProcessLocked(app, app.waitingToKill);
15970                success = false;
15971            } else {
15972                if (true) {
15973                    long oldId = Binder.clearCallingIdentity();
15974                    try {
15975                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15976                    } catch (Exception e) {
15977                        Slog.w(TAG, "Failed setting process group of " + app.pid
15978                                + " to " + app.curSchedGroup);
15979                        e.printStackTrace();
15980                    } finally {
15981                        Binder.restoreCallingIdentity(oldId);
15982                    }
15983                } else {
15984                    if (app.thread != null) {
15985                        try {
15986                            app.thread.setSchedulingGroup(app.curSchedGroup);
15987                        } catch (RemoteException e) {
15988                        }
15989                    }
15990                }
15991                Process.setSwappiness(app.pid,
15992                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15993            }
15994        }
15995        if (app.repForegroundActivities != app.foregroundActivities) {
15996            app.repForegroundActivities = app.foregroundActivities;
15997            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15998        }
15999        if (app.repProcState != app.curProcState) {
16000            app.repProcState = app.curProcState;
16001            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16002            if (app.thread != null) {
16003                try {
16004                    if (false) {
16005                        //RuntimeException h = new RuntimeException("here");
16006                        Slog.i(TAG, "Sending new process state " + app.repProcState
16007                                + " to " + app /*, h*/);
16008                    }
16009                    app.thread.setProcessState(app.repProcState);
16010                } catch (RemoteException e) {
16011                }
16012            }
16013        }
16014        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16015                app.setProcState)) {
16016            app.lastStateTime = now;
16017            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16018                    isSleeping(), now);
16019            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16020                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16021                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16022                    + (app.nextPssTime-now) + ": " + app);
16023        } else {
16024            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16025                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16026                requestPssLocked(app, app.setProcState);
16027                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16028                        isSleeping(), now);
16029            } else if (false && DEBUG_PSS) {
16030                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16031            }
16032        }
16033        if (app.setProcState != app.curProcState) {
16034            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16035                    "Proc state change of " + app.processName
16036                    + " to " + app.curProcState);
16037            app.setProcState = app.curProcState;
16038            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16039                app.notCachedSinceIdle = false;
16040            }
16041            if (!doingAll) {
16042                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
16043            } else {
16044                app.procStateChanged = true;
16045            }
16046        }
16047
16048        if (changes != 0) {
16049            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16050            int i = mPendingProcessChanges.size()-1;
16051            ProcessChangeItem item = null;
16052            while (i >= 0) {
16053                item = mPendingProcessChanges.get(i);
16054                if (item.pid == app.pid) {
16055                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16056                    break;
16057                }
16058                i--;
16059            }
16060            if (i < 0) {
16061                // No existing item in pending changes; need a new one.
16062                final int NA = mAvailProcessChanges.size();
16063                if (NA > 0) {
16064                    item = mAvailProcessChanges.remove(NA-1);
16065                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16066                } else {
16067                    item = new ProcessChangeItem();
16068                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16069                }
16070                item.changes = 0;
16071                item.pid = app.pid;
16072                item.uid = app.info.uid;
16073                if (mPendingProcessChanges.size() == 0) {
16074                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16075                            "*** Enqueueing dispatch processes changed!");
16076                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16077                }
16078                mPendingProcessChanges.add(item);
16079            }
16080            item.changes |= changes;
16081            item.processState = app.repProcState;
16082            item.foregroundActivities = app.repForegroundActivities;
16083            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16084                    + Integer.toHexString(System.identityHashCode(item))
16085                    + " " + app.toShortString() + ": changes=" + item.changes
16086                    + " procState=" + item.processState
16087                    + " foreground=" + item.foregroundActivities
16088                    + " type=" + app.adjType + " source=" + app.adjSource
16089                    + " target=" + app.adjTarget);
16090        }
16091
16092        return success;
16093    }
16094
16095    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16096        if (proc.thread != null && proc.baseProcessTracker != null) {
16097            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16098        }
16099    }
16100
16101    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16102            ProcessRecord TOP_APP, boolean doingAll, long now) {
16103        if (app.thread == null) {
16104            return false;
16105        }
16106
16107        final boolean wasKeeping = app.keeping;
16108
16109        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16110
16111        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16112    }
16113
16114    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16115            boolean oomAdj) {
16116        if (isForeground != proc.foregroundServices) {
16117            proc.foregroundServices = isForeground;
16118            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16119                    proc.info.uid);
16120            if (isForeground) {
16121                if (curProcs == null) {
16122                    curProcs = new ArrayList<ProcessRecord>();
16123                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16124                }
16125                if (!curProcs.contains(proc)) {
16126                    curProcs.add(proc);
16127                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16128                            proc.info.packageName, proc.info.uid);
16129                }
16130            } else {
16131                if (curProcs != null) {
16132                    if (curProcs.remove(proc)) {
16133                        mBatteryStatsService.noteEvent(
16134                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16135                                proc.info.packageName, proc.info.uid);
16136                        if (curProcs.size() <= 0) {
16137                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16138                        }
16139                    }
16140                }
16141            }
16142            if (oomAdj) {
16143                updateOomAdjLocked();
16144            }
16145        }
16146    }
16147
16148    private final ActivityRecord resumedAppLocked() {
16149        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16150        String pkg;
16151        int uid;
16152        if (act != null && !act.sleeping) {
16153            pkg = act.packageName;
16154            uid = act.info.applicationInfo.uid;
16155        } else {
16156            pkg = null;
16157            uid = -1;
16158        }
16159        // Has the UID or resumed package name changed?
16160        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16161                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16162            if (mCurResumedPackage != null) {
16163                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16164                        mCurResumedPackage, mCurResumedUid);
16165            }
16166            mCurResumedPackage = pkg;
16167            mCurResumedUid = uid;
16168            if (mCurResumedPackage != null) {
16169                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16170                        mCurResumedPackage, mCurResumedUid);
16171            }
16172        }
16173        return act;
16174    }
16175
16176    final boolean updateOomAdjLocked(ProcessRecord app) {
16177        final ActivityRecord TOP_ACT = resumedAppLocked();
16178        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16179        final boolean wasCached = app.cached;
16180
16181        mAdjSeq++;
16182
16183        // This is the desired cached adjusment we want to tell it to use.
16184        // If our app is currently cached, we know it, and that is it.  Otherwise,
16185        // we don't know it yet, and it needs to now be cached we will then
16186        // need to do a complete oom adj.
16187        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16188                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16189        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16190                SystemClock.uptimeMillis());
16191        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16192            // Changed to/from cached state, so apps after it in the LRU
16193            // list may also be changed.
16194            updateOomAdjLocked();
16195        }
16196        return success;
16197    }
16198
16199    final void updateOomAdjLocked() {
16200        final ActivityRecord TOP_ACT = resumedAppLocked();
16201        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16202        final long now = SystemClock.uptimeMillis();
16203        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16204        final int N = mLruProcesses.size();
16205
16206        if (false) {
16207            RuntimeException e = new RuntimeException();
16208            e.fillInStackTrace();
16209            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16210        }
16211
16212        mAdjSeq++;
16213        mNewNumServiceProcs = 0;
16214        mNewNumAServiceProcs = 0;
16215
16216        final int emptyProcessLimit;
16217        final int cachedProcessLimit;
16218        if (mProcessLimit <= 0) {
16219            emptyProcessLimit = cachedProcessLimit = 0;
16220        } else if (mProcessLimit == 1) {
16221            emptyProcessLimit = 1;
16222            cachedProcessLimit = 0;
16223        } else {
16224            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16225            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16226        }
16227
16228        // Let's determine how many processes we have running vs.
16229        // how many slots we have for background processes; we may want
16230        // to put multiple processes in a slot of there are enough of
16231        // them.
16232        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16233                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16234        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16235        if (numEmptyProcs > cachedProcessLimit) {
16236            // If there are more empty processes than our limit on cached
16237            // processes, then use the cached process limit for the factor.
16238            // This ensures that the really old empty processes get pushed
16239            // down to the bottom, so if we are running low on memory we will
16240            // have a better chance at keeping around more cached processes
16241            // instead of a gazillion empty processes.
16242            numEmptyProcs = cachedProcessLimit;
16243        }
16244        int emptyFactor = numEmptyProcs/numSlots;
16245        if (emptyFactor < 1) emptyFactor = 1;
16246        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16247        if (cachedFactor < 1) cachedFactor = 1;
16248        int stepCached = 0;
16249        int stepEmpty = 0;
16250        int numCached = 0;
16251        int numEmpty = 0;
16252        int numTrimming = 0;
16253
16254        mNumNonCachedProcs = 0;
16255        mNumCachedHiddenProcs = 0;
16256
16257        // First update the OOM adjustment for each of the
16258        // application processes based on their current state.
16259        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16260        int nextCachedAdj = curCachedAdj+1;
16261        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16262        int nextEmptyAdj = curEmptyAdj+2;
16263        for (int i=N-1; i>=0; i--) {
16264            ProcessRecord app = mLruProcesses.get(i);
16265            if (!app.killedByAm && app.thread != null) {
16266                app.procStateChanged = false;
16267                final boolean wasKeeping = app.keeping;
16268                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16269
16270                // If we haven't yet assigned the final cached adj
16271                // to the process, do that now.
16272                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16273                    switch (app.curProcState) {
16274                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16275                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16276                            // This process is a cached process holding activities...
16277                            // assign it the next cached value for that type, and then
16278                            // step that cached level.
16279                            app.curRawAdj = curCachedAdj;
16280                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16281                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16282                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16283                                    + ")");
16284                            if (curCachedAdj != nextCachedAdj) {
16285                                stepCached++;
16286                                if (stepCached >= cachedFactor) {
16287                                    stepCached = 0;
16288                                    curCachedAdj = nextCachedAdj;
16289                                    nextCachedAdj += 2;
16290                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16291                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16292                                    }
16293                                }
16294                            }
16295                            break;
16296                        default:
16297                            // For everything else, assign next empty cached process
16298                            // level and bump that up.  Note that this means that
16299                            // long-running services that have dropped down to the
16300                            // cached level will be treated as empty (since their process
16301                            // state is still as a service), which is what we want.
16302                            app.curRawAdj = curEmptyAdj;
16303                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16304                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16305                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16306                                    + ")");
16307                            if (curEmptyAdj != nextEmptyAdj) {
16308                                stepEmpty++;
16309                                if (stepEmpty >= emptyFactor) {
16310                                    stepEmpty = 0;
16311                                    curEmptyAdj = nextEmptyAdj;
16312                                    nextEmptyAdj += 2;
16313                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16314                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16315                                    }
16316                                }
16317                            }
16318                            break;
16319                    }
16320                }
16321
16322                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16323
16324                // Count the number of process types.
16325                switch (app.curProcState) {
16326                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16327                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16328                        mNumCachedHiddenProcs++;
16329                        numCached++;
16330                        if (numCached > cachedProcessLimit) {
16331                            killUnneededProcessLocked(app, "cached #" + numCached);
16332                        }
16333                        break;
16334                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16335                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16336                                && app.lastActivityTime < oldTime) {
16337                            killUnneededProcessLocked(app, "empty for "
16338                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16339                                    / 1000) + "s");
16340                        } else {
16341                            numEmpty++;
16342                            if (numEmpty > emptyProcessLimit) {
16343                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16344                            }
16345                        }
16346                        break;
16347                    default:
16348                        mNumNonCachedProcs++;
16349                        break;
16350                }
16351
16352                if (app.isolated && app.services.size() <= 0) {
16353                    // If this is an isolated process, and there are no
16354                    // services running in it, then the process is no longer
16355                    // needed.  We agressively kill these because we can by
16356                    // definition not re-use the same process again, and it is
16357                    // good to avoid having whatever code was running in them
16358                    // left sitting around after no longer needed.
16359                    killUnneededProcessLocked(app, "isolated not needed");
16360                }
16361
16362                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16363                        && !app.killedByAm) {
16364                    numTrimming++;
16365                }
16366            }
16367        }
16368
16369        mNumServiceProcs = mNewNumServiceProcs;
16370
16371        // Now determine the memory trimming level of background processes.
16372        // Unfortunately we need to start at the back of the list to do this
16373        // properly.  We only do this if the number of background apps we
16374        // are managing to keep around is less than half the maximum we desire;
16375        // if we are keeping a good number around, we'll let them use whatever
16376        // memory they want.
16377        final int numCachedAndEmpty = numCached + numEmpty;
16378        int memFactor;
16379        if (numCached <= ProcessList.TRIM_CACHED_APPS
16380                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16381            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16382                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16383            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16384                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16385            } else {
16386                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16387            }
16388        } else {
16389            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16390        }
16391        // We always allow the memory level to go up (better).  We only allow it to go
16392        // down if we are in a state where that is allowed, *and* the total number of processes
16393        // has gone down since last time.
16394        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16395                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16396                + " last=" + mLastNumProcesses);
16397        if (memFactor > mLastMemoryLevel) {
16398            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16399                memFactor = mLastMemoryLevel;
16400                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16401            }
16402        }
16403        mLastMemoryLevel = memFactor;
16404        mLastNumProcesses = mLruProcesses.size();
16405        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16406        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16407        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16408            if (mLowRamStartTime == 0) {
16409                mLowRamStartTime = now;
16410            }
16411            int step = 0;
16412            int fgTrimLevel;
16413            switch (memFactor) {
16414                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16415                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16416                    break;
16417                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16418                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16419                    break;
16420                default:
16421                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16422                    break;
16423            }
16424            int factor = numTrimming/3;
16425            int minFactor = 2;
16426            if (mHomeProcess != null) minFactor++;
16427            if (mPreviousProcess != null) minFactor++;
16428            if (factor < minFactor) factor = minFactor;
16429            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16430            for (int i=N-1; i>=0; i--) {
16431                ProcessRecord app = mLruProcesses.get(i);
16432                if (allChanged || app.procStateChanged) {
16433                    setProcessTrackerState(app, trackerMemFactor, now);
16434                    app.procStateChanged = false;
16435                }
16436                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16437                        && !app.killedByAm) {
16438                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16439                        try {
16440                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16441                                    "Trimming memory of " + app.processName
16442                                    + " to " + curLevel);
16443                            app.thread.scheduleTrimMemory(curLevel);
16444                        } catch (RemoteException e) {
16445                        }
16446                        if (false) {
16447                            // For now we won't do this; our memory trimming seems
16448                            // to be good enough at this point that destroying
16449                            // activities causes more harm than good.
16450                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16451                                    && app != mHomeProcess && app != mPreviousProcess) {
16452                                // Need to do this on its own message because the stack may not
16453                                // be in a consistent state at this point.
16454                                // For these apps we will also finish their activities
16455                                // to help them free memory.
16456                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16457                            }
16458                        }
16459                    }
16460                    app.trimMemoryLevel = curLevel;
16461                    step++;
16462                    if (step >= factor) {
16463                        step = 0;
16464                        switch (curLevel) {
16465                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16466                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16467                                break;
16468                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16469                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16470                                break;
16471                        }
16472                    }
16473                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16474                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16475                            && app.thread != null) {
16476                        try {
16477                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16478                                    "Trimming memory of heavy-weight " + app.processName
16479                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16480                            app.thread.scheduleTrimMemory(
16481                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16482                        } catch (RemoteException e) {
16483                        }
16484                    }
16485                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16486                } else {
16487                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16488                            || app.systemNoUi) && app.pendingUiClean) {
16489                        // If this application is now in the background and it
16490                        // had done UI, then give it the special trim level to
16491                        // have it free UI resources.
16492                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16493                        if (app.trimMemoryLevel < level && app.thread != null) {
16494                            try {
16495                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16496                                        "Trimming memory of bg-ui " + app.processName
16497                                        + " to " + level);
16498                                app.thread.scheduleTrimMemory(level);
16499                            } catch (RemoteException e) {
16500                            }
16501                        }
16502                        app.pendingUiClean = false;
16503                    }
16504                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16505                        try {
16506                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16507                                    "Trimming memory of fg " + app.processName
16508                                    + " to " + fgTrimLevel);
16509                            app.thread.scheduleTrimMemory(fgTrimLevel);
16510                        } catch (RemoteException e) {
16511                        }
16512                    }
16513                    app.trimMemoryLevel = fgTrimLevel;
16514                }
16515            }
16516        } else {
16517            if (mLowRamStartTime != 0) {
16518                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16519                mLowRamStartTime = 0;
16520            }
16521            for (int i=N-1; i>=0; i--) {
16522                ProcessRecord app = mLruProcesses.get(i);
16523                if (allChanged || app.procStateChanged) {
16524                    setProcessTrackerState(app, trackerMemFactor, now);
16525                    app.procStateChanged = false;
16526                }
16527                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16528                        || app.systemNoUi) && app.pendingUiClean) {
16529                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16530                            && app.thread != null) {
16531                        try {
16532                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16533                                    "Trimming memory of ui hidden " + app.processName
16534                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16535                            app.thread.scheduleTrimMemory(
16536                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16537                        } catch (RemoteException e) {
16538                        }
16539                    }
16540                    app.pendingUiClean = false;
16541                }
16542                app.trimMemoryLevel = 0;
16543            }
16544        }
16545
16546        if (mAlwaysFinishActivities) {
16547            // Need to do this on its own message because the stack may not
16548            // be in a consistent state at this point.
16549            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16550        }
16551
16552        if (allChanged) {
16553            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16554        }
16555
16556        if (mProcessStats.shouldWriteNowLocked(now)) {
16557            mHandler.post(new Runnable() {
16558                @Override public void run() {
16559                    synchronized (ActivityManagerService.this) {
16560                        mProcessStats.writeStateAsyncLocked();
16561                    }
16562                }
16563            });
16564        }
16565
16566        if (DEBUG_OOM_ADJ) {
16567            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16568        }
16569    }
16570
16571    final void trimApplications() {
16572        synchronized (this) {
16573            int i;
16574
16575            // First remove any unused application processes whose package
16576            // has been removed.
16577            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16578                final ProcessRecord app = mRemovedProcesses.get(i);
16579                if (app.activities.size() == 0
16580                        && app.curReceiver == null && app.services.size() == 0) {
16581                    Slog.i(
16582                        TAG, "Exiting empty application process "
16583                        + app.processName + " ("
16584                        + (app.thread != null ? app.thread.asBinder() : null)
16585                        + ")\n");
16586                    if (app.pid > 0 && app.pid != MY_PID) {
16587                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16588                                app.processName, app.setAdj, "empty");
16589                        app.killedByAm = true;
16590                        Process.killProcessQuiet(app.pid);
16591                    } else {
16592                        try {
16593                            app.thread.scheduleExit();
16594                        } catch (Exception e) {
16595                            // Ignore exceptions.
16596                        }
16597                    }
16598                    cleanUpApplicationRecordLocked(app, false, true, -1);
16599                    mRemovedProcesses.remove(i);
16600
16601                    if (app.persistent) {
16602                        addAppLocked(app.info, false, null /* ABI override */);
16603                    }
16604                }
16605            }
16606
16607            // Now update the oom adj for all processes.
16608            updateOomAdjLocked();
16609        }
16610    }
16611
16612    /** This method sends the specified signal to each of the persistent apps */
16613    public void signalPersistentProcesses(int sig) throws RemoteException {
16614        if (sig != Process.SIGNAL_USR1) {
16615            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16616        }
16617
16618        synchronized (this) {
16619            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16620                    != PackageManager.PERMISSION_GRANTED) {
16621                throw new SecurityException("Requires permission "
16622                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16623            }
16624
16625            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16626                ProcessRecord r = mLruProcesses.get(i);
16627                if (r.thread != null && r.persistent) {
16628                    Process.sendSignal(r.pid, sig);
16629                }
16630            }
16631        }
16632    }
16633
16634    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16635        if (proc == null || proc == mProfileProc) {
16636            proc = mProfileProc;
16637            path = mProfileFile;
16638            profileType = mProfileType;
16639            clearProfilerLocked();
16640        }
16641        if (proc == null) {
16642            return;
16643        }
16644        try {
16645            proc.thread.profilerControl(false, path, null, profileType);
16646        } catch (RemoteException e) {
16647            throw new IllegalStateException("Process disappeared");
16648        }
16649    }
16650
16651    private void clearProfilerLocked() {
16652        if (mProfileFd != null) {
16653            try {
16654                mProfileFd.close();
16655            } catch (IOException e) {
16656            }
16657        }
16658        mProfileApp = null;
16659        mProfileProc = null;
16660        mProfileFile = null;
16661        mProfileType = 0;
16662        mAutoStopProfiler = false;
16663    }
16664
16665    public boolean profileControl(String process, int userId, boolean start,
16666            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16667
16668        try {
16669            synchronized (this) {
16670                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16671                // its own permission.
16672                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16673                        != PackageManager.PERMISSION_GRANTED) {
16674                    throw new SecurityException("Requires permission "
16675                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16676                }
16677
16678                if (start && fd == null) {
16679                    throw new IllegalArgumentException("null fd");
16680                }
16681
16682                ProcessRecord proc = null;
16683                if (process != null) {
16684                    proc = findProcessLocked(process, userId, "profileControl");
16685                }
16686
16687                if (start && (proc == null || proc.thread == null)) {
16688                    throw new IllegalArgumentException("Unknown process: " + process);
16689                }
16690
16691                if (start) {
16692                    stopProfilerLocked(null, null, 0);
16693                    setProfileApp(proc.info, proc.processName, path, fd, false);
16694                    mProfileProc = proc;
16695                    mProfileType = profileType;
16696                    try {
16697                        fd = fd.dup();
16698                    } catch (IOException e) {
16699                        fd = null;
16700                    }
16701                    proc.thread.profilerControl(start, path, fd, profileType);
16702                    fd = null;
16703                    mProfileFd = null;
16704                } else {
16705                    stopProfilerLocked(proc, path, profileType);
16706                    if (fd != null) {
16707                        try {
16708                            fd.close();
16709                        } catch (IOException e) {
16710                        }
16711                    }
16712                }
16713
16714                return true;
16715            }
16716        } catch (RemoteException e) {
16717            throw new IllegalStateException("Process disappeared");
16718        } finally {
16719            if (fd != null) {
16720                try {
16721                    fd.close();
16722                } catch (IOException e) {
16723                }
16724            }
16725        }
16726    }
16727
16728    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16729        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16730                userId, true, true, callName, null);
16731        ProcessRecord proc = null;
16732        try {
16733            int pid = Integer.parseInt(process);
16734            synchronized (mPidsSelfLocked) {
16735                proc = mPidsSelfLocked.get(pid);
16736            }
16737        } catch (NumberFormatException e) {
16738        }
16739
16740        if (proc == null) {
16741            ArrayMap<String, SparseArray<ProcessRecord>> all
16742                    = mProcessNames.getMap();
16743            SparseArray<ProcessRecord> procs = all.get(process);
16744            if (procs != null && procs.size() > 0) {
16745                proc = procs.valueAt(0);
16746                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16747                    for (int i=1; i<procs.size(); i++) {
16748                        ProcessRecord thisProc = procs.valueAt(i);
16749                        if (thisProc.userId == userId) {
16750                            proc = thisProc;
16751                            break;
16752                        }
16753                    }
16754                }
16755            }
16756        }
16757
16758        return proc;
16759    }
16760
16761    public boolean dumpHeap(String process, int userId, boolean managed,
16762            String path, ParcelFileDescriptor fd) throws RemoteException {
16763
16764        try {
16765            synchronized (this) {
16766                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16767                // its own permission (same as profileControl).
16768                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16769                        != PackageManager.PERMISSION_GRANTED) {
16770                    throw new SecurityException("Requires permission "
16771                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16772                }
16773
16774                if (fd == null) {
16775                    throw new IllegalArgumentException("null fd");
16776                }
16777
16778                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16779                if (proc == null || proc.thread == null) {
16780                    throw new IllegalArgumentException("Unknown process: " + process);
16781                }
16782
16783                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16784                if (!isDebuggable) {
16785                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16786                        throw new SecurityException("Process not debuggable: " + proc);
16787                    }
16788                }
16789
16790                proc.thread.dumpHeap(managed, path, fd);
16791                fd = null;
16792                return true;
16793            }
16794        } catch (RemoteException e) {
16795            throw new IllegalStateException("Process disappeared");
16796        } finally {
16797            if (fd != null) {
16798                try {
16799                    fd.close();
16800                } catch (IOException e) {
16801                }
16802            }
16803        }
16804    }
16805
16806    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16807    public void monitor() {
16808        synchronized (this) { }
16809    }
16810
16811    void onCoreSettingsChange(Bundle settings) {
16812        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16813            ProcessRecord processRecord = mLruProcesses.get(i);
16814            try {
16815                if (processRecord.thread != null) {
16816                    processRecord.thread.setCoreSettings(settings);
16817                }
16818            } catch (RemoteException re) {
16819                /* ignore */
16820            }
16821        }
16822    }
16823
16824    // Multi-user methods
16825
16826    /**
16827     * Start user, if its not already running, but don't bring it to foreground.
16828     */
16829    @Override
16830    public boolean startUserInBackground(final int userId) {
16831        return startUser(userId, /* foreground */ false);
16832    }
16833
16834    /**
16835     * Refreshes the list of users related to the current user when either a
16836     * user switch happens or when a new related user is started in the
16837     * background.
16838     */
16839    private void updateCurrentProfileIdsLocked() {
16840        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16841                mCurrentUserId, false /* enabledOnly */);
16842        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16843        for (int i = 0; i < currentProfileIds.length; i++) {
16844            currentProfileIds[i] = profiles.get(i).id;
16845        }
16846        mCurrentProfileIds = currentProfileIds;
16847    }
16848
16849    private Set getProfileIdsLocked(int userId) {
16850        Set userIds = new HashSet<Integer>();
16851        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16852                userId, false /* enabledOnly */);
16853        for (UserInfo user : profiles) {
16854            userIds.add(Integer.valueOf(user.id));
16855        }
16856        return userIds;
16857    }
16858
16859    @Override
16860    public boolean switchUser(final int userId) {
16861        return startUser(userId, /* foregound */ true);
16862    }
16863
16864    private boolean startUser(final int userId, boolean foreground) {
16865        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16866                != PackageManager.PERMISSION_GRANTED) {
16867            String msg = "Permission Denial: switchUser() from pid="
16868                    + Binder.getCallingPid()
16869                    + ", uid=" + Binder.getCallingUid()
16870                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16871            Slog.w(TAG, msg);
16872            throw new SecurityException(msg);
16873        }
16874
16875        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16876
16877        final long ident = Binder.clearCallingIdentity();
16878        try {
16879            synchronized (this) {
16880                final int oldUserId = mCurrentUserId;
16881                if (oldUserId == userId) {
16882                    return true;
16883                }
16884
16885                mStackSupervisor.setLockTaskModeLocked(null, false);
16886
16887                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16888                if (userInfo == null) {
16889                    Slog.w(TAG, "No user info for user #" + userId);
16890                    return false;
16891                }
16892
16893                if (foreground) {
16894                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16895                            R.anim.screen_user_enter);
16896                }
16897
16898                boolean needStart = false;
16899
16900                // If the user we are switching to is not currently started, then
16901                // we need to start it now.
16902                if (mStartedUsers.get(userId) == null) {
16903                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16904                    updateStartedUserArrayLocked();
16905                    needStart = true;
16906                }
16907
16908                final Integer userIdInt = Integer.valueOf(userId);
16909                mUserLru.remove(userIdInt);
16910                mUserLru.add(userIdInt);
16911
16912                if (foreground) {
16913                    mCurrentUserId = userId;
16914                    updateCurrentProfileIdsLocked();
16915                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16916                    // Once the internal notion of the active user has switched, we lock the device
16917                    // with the option to show the user switcher on the keyguard.
16918                    mWindowManager.lockNow(null);
16919                } else {
16920                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16921                    updateCurrentProfileIdsLocked();
16922                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16923                    mUserLru.remove(currentUserIdInt);
16924                    mUserLru.add(currentUserIdInt);
16925                }
16926
16927                final UserStartedState uss = mStartedUsers.get(userId);
16928
16929                // Make sure user is in the started state.  If it is currently
16930                // stopping, we need to knock that off.
16931                if (uss.mState == UserStartedState.STATE_STOPPING) {
16932                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16933                    // so we can just fairly silently bring the user back from
16934                    // the almost-dead.
16935                    uss.mState = UserStartedState.STATE_RUNNING;
16936                    updateStartedUserArrayLocked();
16937                    needStart = true;
16938                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16939                    // This means ACTION_SHUTDOWN has been sent, so we will
16940                    // need to treat this as a new boot of the user.
16941                    uss.mState = UserStartedState.STATE_BOOTING;
16942                    updateStartedUserArrayLocked();
16943                    needStart = true;
16944                }
16945
16946                if (uss.mState == UserStartedState.STATE_BOOTING) {
16947                    // Booting up a new user, need to tell system services about it.
16948                    // Note that this is on the same handler as scheduling of broadcasts,
16949                    // which is important because it needs to go first.
16950                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16951                }
16952
16953                if (foreground) {
16954                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16955                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16956                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16957                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16958                            oldUserId, userId, uss));
16959                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16960                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16961                }
16962
16963                if (needStart) {
16964                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16965                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16966                            | Intent.FLAG_RECEIVER_FOREGROUND);
16967                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16968                    broadcastIntentLocked(null, null, intent,
16969                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16970                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16971                }
16972
16973                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16974                    if (userId != UserHandle.USER_OWNER) {
16975                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16976                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16977                        broadcastIntentLocked(null, null, intent, null,
16978                                new IIntentReceiver.Stub() {
16979                                    public void performReceive(Intent intent, int resultCode,
16980                                            String data, Bundle extras, boolean ordered,
16981                                            boolean sticky, int sendingUser) {
16982                                        userInitialized(uss, userId);
16983                                    }
16984                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16985                                true, false, MY_PID, Process.SYSTEM_UID,
16986                                userId);
16987                        uss.initializing = true;
16988                    } else {
16989                        getUserManagerLocked().makeInitialized(userInfo.id);
16990                    }
16991                }
16992
16993                if (foreground) {
16994                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16995                    if (homeInFront) {
16996                        startHomeActivityLocked(userId);
16997                    } else {
16998                        mStackSupervisor.resumeTopActivitiesLocked();
16999                    }
17000                    EventLogTags.writeAmSwitchUser(userId);
17001                    getUserManagerLocked().userForeground(userId);
17002                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17003                } else {
17004                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17005                }
17006
17007                if (needStart) {
17008                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17009                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17010                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17011                    broadcastIntentLocked(null, null, intent,
17012                            null, new IIntentReceiver.Stub() {
17013                                @Override
17014                                public void performReceive(Intent intent, int resultCode, String data,
17015                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17016                                        throws RemoteException {
17017                                }
17018                            }, 0, null, null,
17019                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17020                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17021                }
17022            }
17023        } finally {
17024            Binder.restoreCallingIdentity(ident);
17025        }
17026
17027        return true;
17028    }
17029
17030    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17031        long ident = Binder.clearCallingIdentity();
17032        try {
17033            Intent intent;
17034            if (oldUserId >= 0) {
17035                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17036                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17037                        | Intent.FLAG_RECEIVER_FOREGROUND);
17038                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
17039                broadcastIntentLocked(null, null, intent,
17040                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17041                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
17042            }
17043            if (newUserId >= 0) {
17044                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17045                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17046                        | Intent.FLAG_RECEIVER_FOREGROUND);
17047                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17048                broadcastIntentLocked(null, null, intent,
17049                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17050                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
17051                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17052                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17053                        | Intent.FLAG_RECEIVER_FOREGROUND);
17054                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17055                broadcastIntentLocked(null, null, intent,
17056                        null, null, 0, null, null,
17057                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17058                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17059            }
17060        } finally {
17061            Binder.restoreCallingIdentity(ident);
17062        }
17063    }
17064
17065    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17066            final int newUserId) {
17067        final int N = mUserSwitchObservers.beginBroadcast();
17068        if (N > 0) {
17069            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17070                int mCount = 0;
17071                @Override
17072                public void sendResult(Bundle data) throws RemoteException {
17073                    synchronized (ActivityManagerService.this) {
17074                        if (mCurUserSwitchCallback == this) {
17075                            mCount++;
17076                            if (mCount == N) {
17077                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17078                            }
17079                        }
17080                    }
17081                }
17082            };
17083            synchronized (this) {
17084                uss.switching = true;
17085                mCurUserSwitchCallback = callback;
17086            }
17087            for (int i=0; i<N; i++) {
17088                try {
17089                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17090                            newUserId, callback);
17091                } catch (RemoteException e) {
17092                }
17093            }
17094        } else {
17095            synchronized (this) {
17096                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17097            }
17098        }
17099        mUserSwitchObservers.finishBroadcast();
17100    }
17101
17102    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17103        synchronized (this) {
17104            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17105            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17106        }
17107    }
17108
17109    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17110        mCurUserSwitchCallback = null;
17111        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17112        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17113                oldUserId, newUserId, uss));
17114    }
17115
17116    void userInitialized(UserStartedState uss, int newUserId) {
17117        completeSwitchAndInitalize(uss, newUserId, true, false);
17118    }
17119
17120    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17121        completeSwitchAndInitalize(uss, newUserId, false, true);
17122    }
17123
17124    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17125            boolean clearInitializing, boolean clearSwitching) {
17126        boolean unfrozen = false;
17127        synchronized (this) {
17128            if (clearInitializing) {
17129                uss.initializing = false;
17130                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17131            }
17132            if (clearSwitching) {
17133                uss.switching = false;
17134            }
17135            if (!uss.switching && !uss.initializing) {
17136                mWindowManager.stopFreezingScreen();
17137                unfrozen = true;
17138            }
17139        }
17140        if (unfrozen) {
17141            final int N = mUserSwitchObservers.beginBroadcast();
17142            for (int i=0; i<N; i++) {
17143                try {
17144                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17145                } catch (RemoteException e) {
17146                }
17147            }
17148            mUserSwitchObservers.finishBroadcast();
17149        }
17150    }
17151
17152    void scheduleStartProfilesLocked() {
17153        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17154            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17155                    DateUtils.SECOND_IN_MILLIS);
17156        }
17157    }
17158
17159    void startProfilesLocked() {
17160        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17161        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17162                mCurrentUserId, false /* enabledOnly */);
17163        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17164        for (UserInfo user : profiles) {
17165            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17166                    && user.id != mCurrentUserId) {
17167                toStart.add(user);
17168            }
17169        }
17170        final int n = toStart.size();
17171        int i = 0;
17172        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17173            startUserInBackground(toStart.get(i).id);
17174        }
17175        if (i < n) {
17176            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17177        }
17178    }
17179
17180    void finishUserBoot(UserStartedState uss) {
17181        synchronized (this) {
17182            if (uss.mState == UserStartedState.STATE_BOOTING
17183                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17184                uss.mState = UserStartedState.STATE_RUNNING;
17185                final int userId = uss.mHandle.getIdentifier();
17186                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17187                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17188                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17189                broadcastIntentLocked(null, null, intent,
17190                        null, null, 0, null, null,
17191                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17192                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17193            }
17194        }
17195    }
17196
17197    void finishUserSwitch(UserStartedState uss) {
17198        synchronized (this) {
17199            finishUserBoot(uss);
17200
17201            startProfilesLocked();
17202
17203            int num = mUserLru.size();
17204            int i = 0;
17205            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17206                Integer oldUserId = mUserLru.get(i);
17207                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17208                if (oldUss == null) {
17209                    // Shouldn't happen, but be sane if it does.
17210                    mUserLru.remove(i);
17211                    num--;
17212                    continue;
17213                }
17214                if (oldUss.mState == UserStartedState.STATE_STOPPING
17215                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17216                    // This user is already stopping, doesn't count.
17217                    num--;
17218                    i++;
17219                    continue;
17220                }
17221                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17222                    // Owner and current can't be stopped, but count as running.
17223                    i++;
17224                    continue;
17225                }
17226                // This is a user to be stopped.
17227                stopUserLocked(oldUserId, null);
17228                num--;
17229                i++;
17230            }
17231        }
17232    }
17233
17234    @Override
17235    public int stopUser(final int userId, final IStopUserCallback callback) {
17236        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17237                != PackageManager.PERMISSION_GRANTED) {
17238            String msg = "Permission Denial: switchUser() from pid="
17239                    + Binder.getCallingPid()
17240                    + ", uid=" + Binder.getCallingUid()
17241                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17242            Slog.w(TAG, msg);
17243            throw new SecurityException(msg);
17244        }
17245        if (userId <= 0) {
17246            throw new IllegalArgumentException("Can't stop primary user " + userId);
17247        }
17248        synchronized (this) {
17249            return stopUserLocked(userId, callback);
17250        }
17251    }
17252
17253    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17254        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17255        if (mCurrentUserId == userId) {
17256            return ActivityManager.USER_OP_IS_CURRENT;
17257        }
17258
17259        final UserStartedState uss = mStartedUsers.get(userId);
17260        if (uss == null) {
17261            // User is not started, nothing to do...  but we do need to
17262            // callback if requested.
17263            if (callback != null) {
17264                mHandler.post(new Runnable() {
17265                    @Override
17266                    public void run() {
17267                        try {
17268                            callback.userStopped(userId);
17269                        } catch (RemoteException e) {
17270                        }
17271                    }
17272                });
17273            }
17274            return ActivityManager.USER_OP_SUCCESS;
17275        }
17276
17277        if (callback != null) {
17278            uss.mStopCallbacks.add(callback);
17279        }
17280
17281        if (uss.mState != UserStartedState.STATE_STOPPING
17282                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17283            uss.mState = UserStartedState.STATE_STOPPING;
17284            updateStartedUserArrayLocked();
17285
17286            long ident = Binder.clearCallingIdentity();
17287            try {
17288                // We are going to broadcast ACTION_USER_STOPPING and then
17289                // once that is done send a final ACTION_SHUTDOWN and then
17290                // stop the user.
17291                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17292                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17293                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17294                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17295                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17296                // This is the result receiver for the final shutdown broadcast.
17297                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17298                    @Override
17299                    public void performReceive(Intent intent, int resultCode, String data,
17300                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17301                        finishUserStop(uss);
17302                    }
17303                };
17304                // This is the result receiver for the initial stopping broadcast.
17305                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17306                    @Override
17307                    public void performReceive(Intent intent, int resultCode, String data,
17308                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17309                        // On to the next.
17310                        synchronized (ActivityManagerService.this) {
17311                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17312                                // Whoops, we are being started back up.  Abort, abort!
17313                                return;
17314                            }
17315                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17316                        }
17317                        mSystemServiceManager.stopUser(userId);
17318                        broadcastIntentLocked(null, null, shutdownIntent,
17319                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17320                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17321                    }
17322                };
17323                // Kick things off.
17324                broadcastIntentLocked(null, null, stoppingIntent,
17325                        null, stoppingReceiver, 0, null, null,
17326                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17327                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17328            } finally {
17329                Binder.restoreCallingIdentity(ident);
17330            }
17331        }
17332
17333        return ActivityManager.USER_OP_SUCCESS;
17334    }
17335
17336    void finishUserStop(UserStartedState uss) {
17337        final int userId = uss.mHandle.getIdentifier();
17338        boolean stopped;
17339        ArrayList<IStopUserCallback> callbacks;
17340        synchronized (this) {
17341            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17342            if (mStartedUsers.get(userId) != uss) {
17343                stopped = false;
17344            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17345                stopped = false;
17346            } else {
17347                stopped = true;
17348                // User can no longer run.
17349                mStartedUsers.remove(userId);
17350                mUserLru.remove(Integer.valueOf(userId));
17351                updateStartedUserArrayLocked();
17352
17353                // Clean up all state and processes associated with the user.
17354                // Kill all the processes for the user.
17355                forceStopUserLocked(userId, "finish user");
17356            }
17357        }
17358
17359        for (int i=0; i<callbacks.size(); i++) {
17360            try {
17361                if (stopped) callbacks.get(i).userStopped(userId);
17362                else callbacks.get(i).userStopAborted(userId);
17363            } catch (RemoteException e) {
17364            }
17365        }
17366
17367        if (stopped) {
17368            mSystemServiceManager.cleanupUser(userId);
17369            synchronized (this) {
17370                mStackSupervisor.removeUserLocked(userId);
17371            }
17372        }
17373    }
17374
17375    @Override
17376    public UserInfo getCurrentUser() {
17377        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17378                != PackageManager.PERMISSION_GRANTED) && (
17379                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17380                != PackageManager.PERMISSION_GRANTED)) {
17381            String msg = "Permission Denial: getCurrentUser() from pid="
17382                    + Binder.getCallingPid()
17383                    + ", uid=" + Binder.getCallingUid()
17384                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17385            Slog.w(TAG, msg);
17386            throw new SecurityException(msg);
17387        }
17388        synchronized (this) {
17389            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17390        }
17391    }
17392
17393    int getCurrentUserIdLocked() {
17394        return mCurrentUserId;
17395    }
17396
17397    @Override
17398    public boolean isUserRunning(int userId, boolean orStopped) {
17399        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17400                != PackageManager.PERMISSION_GRANTED) {
17401            String msg = "Permission Denial: isUserRunning() from pid="
17402                    + Binder.getCallingPid()
17403                    + ", uid=" + Binder.getCallingUid()
17404                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17405            Slog.w(TAG, msg);
17406            throw new SecurityException(msg);
17407        }
17408        synchronized (this) {
17409            return isUserRunningLocked(userId, orStopped);
17410        }
17411    }
17412
17413    boolean isUserRunningLocked(int userId, boolean orStopped) {
17414        UserStartedState state = mStartedUsers.get(userId);
17415        if (state == null) {
17416            return false;
17417        }
17418        if (orStopped) {
17419            return true;
17420        }
17421        return state.mState != UserStartedState.STATE_STOPPING
17422                && state.mState != UserStartedState.STATE_SHUTDOWN;
17423    }
17424
17425    @Override
17426    public int[] getRunningUserIds() {
17427        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17428                != PackageManager.PERMISSION_GRANTED) {
17429            String msg = "Permission Denial: isUserRunning() from pid="
17430                    + Binder.getCallingPid()
17431                    + ", uid=" + Binder.getCallingUid()
17432                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17433            Slog.w(TAG, msg);
17434            throw new SecurityException(msg);
17435        }
17436        synchronized (this) {
17437            return mStartedUserArray;
17438        }
17439    }
17440
17441    private void updateStartedUserArrayLocked() {
17442        int num = 0;
17443        for (int i=0; i<mStartedUsers.size();  i++) {
17444            UserStartedState uss = mStartedUsers.valueAt(i);
17445            // This list does not include stopping users.
17446            if (uss.mState != UserStartedState.STATE_STOPPING
17447                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17448                num++;
17449            }
17450        }
17451        mStartedUserArray = new int[num];
17452        num = 0;
17453        for (int i=0; i<mStartedUsers.size();  i++) {
17454            UserStartedState uss = mStartedUsers.valueAt(i);
17455            if (uss.mState != UserStartedState.STATE_STOPPING
17456                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17457                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17458                num++;
17459            }
17460        }
17461    }
17462
17463    @Override
17464    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17465        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17466                != PackageManager.PERMISSION_GRANTED) {
17467            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17468                    + Binder.getCallingPid()
17469                    + ", uid=" + Binder.getCallingUid()
17470                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17471            Slog.w(TAG, msg);
17472            throw new SecurityException(msg);
17473        }
17474
17475        mUserSwitchObservers.register(observer);
17476    }
17477
17478    @Override
17479    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17480        mUserSwitchObservers.unregister(observer);
17481    }
17482
17483    private boolean userExists(int userId) {
17484        if (userId == 0) {
17485            return true;
17486        }
17487        UserManagerService ums = getUserManagerLocked();
17488        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17489    }
17490
17491    int[] getUsersLocked() {
17492        UserManagerService ums = getUserManagerLocked();
17493        return ums != null ? ums.getUserIds() : new int[] { 0 };
17494    }
17495
17496    UserManagerService getUserManagerLocked() {
17497        if (mUserManager == null) {
17498            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17499            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17500        }
17501        return mUserManager;
17502    }
17503
17504    private int applyUserId(int uid, int userId) {
17505        return UserHandle.getUid(userId, uid);
17506    }
17507
17508    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17509        if (info == null) return null;
17510        ApplicationInfo newInfo = new ApplicationInfo(info);
17511        newInfo.uid = applyUserId(info.uid, userId);
17512        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17513                + info.packageName;
17514        return newInfo;
17515    }
17516
17517    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17518        if (aInfo == null
17519                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17520            return aInfo;
17521        }
17522
17523        ActivityInfo info = new ActivityInfo(aInfo);
17524        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17525        return info;
17526    }
17527
17528    private final class LocalService extends ActivityManagerInternal {
17529        @Override
17530        public void goingToSleep() {
17531            ActivityManagerService.this.goingToSleep();
17532        }
17533
17534        @Override
17535        public void wakingUp() {
17536            ActivityManagerService.this.wakingUp();
17537        }
17538    }
17539
17540    /**
17541     * An implementation of IAppTask, that allows an app to manage its own tasks via
17542     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17543     * only the process that calls getAppTasks() can call the AppTask methods.
17544     */
17545    class AppTaskImpl extends IAppTask.Stub {
17546        private int mTaskId;
17547        private int mCallingUid;
17548
17549        public AppTaskImpl(int taskId, int callingUid) {
17550            mTaskId = taskId;
17551            mCallingUid = callingUid;
17552        }
17553
17554        @Override
17555        public void finishAndRemoveTask() {
17556            // Ensure that we are called from the same process that created this AppTask
17557            if (mCallingUid != Binder.getCallingUid()) {
17558                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17559                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17560                return;
17561            }
17562
17563            synchronized (ActivityManagerService.this) {
17564                long origId = Binder.clearCallingIdentity();
17565                try {
17566                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17567                    if (tr != null) {
17568                        // Only kill the process if we are not a new document
17569                        int flags = tr.getBaseIntent().getFlags();
17570                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17571                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17572                        removeTaskByIdLocked(mTaskId,
17573                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17574                    }
17575                } finally {
17576                    Binder.restoreCallingIdentity(origId);
17577                }
17578            }
17579        }
17580
17581        @Override
17582        public ActivityManager.RecentTaskInfo getTaskInfo() {
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 null;
17588            }
17589
17590            synchronized (ActivityManagerService.this) {
17591                long origId = Binder.clearCallingIdentity();
17592                try {
17593                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17594                    if (tr != null) {
17595                        return createRecentTaskInfoFromTaskRecord(tr);
17596                    }
17597                } finally {
17598                    Binder.restoreCallingIdentity(origId);
17599                }
17600                return null;
17601            }
17602        }
17603    }
17604}
17605