ActivityManagerService.java revision c0ffce5ddd6446f1d46a49cdfaeda4a2ce408e1d
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            synchronized (mPidsSelfLocked) {
3048                this.mPidsSelfLocked.put(startResult.pid, app);
3049                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3050                msg.obj = app;
3051                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3052                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3053            }
3054            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3055                    app.processName, app.info.uid);
3056            if (app.isolated) {
3057                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3058            }
3059        } catch (RuntimeException e) {
3060            // XXX do better error recovery.
3061            app.setPid(0);
3062            Slog.e(TAG, "Failure starting process " + app.processName, e);
3063        }
3064    }
3065
3066    void updateUsageStats(ActivityRecord component, boolean resumed) {
3067        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3068        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3069        if (resumed) {
3070            mUsageStatsService.noteResumeComponent(component.realActivity);
3071            synchronized (stats) {
3072                stats.noteActivityResumedLocked(component.app.uid);
3073            }
3074        } else {
3075            mUsageStatsService.notePauseComponent(component.realActivity);
3076            synchronized (stats) {
3077                stats.noteActivityPausedLocked(component.app.uid);
3078            }
3079        }
3080    }
3081
3082    Intent getHomeIntent() {
3083        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3084        intent.setComponent(mTopComponent);
3085        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3086            intent.addCategory(Intent.CATEGORY_HOME);
3087        }
3088        return intent;
3089    }
3090
3091    boolean startHomeActivityLocked(int userId) {
3092        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3093                && mTopAction == null) {
3094            // We are running in factory test mode, but unable to find
3095            // the factory test app, so just sit around displaying the
3096            // error message and don't try to start anything.
3097            return false;
3098        }
3099        Intent intent = getHomeIntent();
3100        ActivityInfo aInfo =
3101            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3102        if (aInfo != null) {
3103            intent.setComponent(new ComponentName(
3104                    aInfo.applicationInfo.packageName, aInfo.name));
3105            // Don't do this if the home app is currently being
3106            // instrumented.
3107            aInfo = new ActivityInfo(aInfo);
3108            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3109            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3110                    aInfo.applicationInfo.uid, true);
3111            if (app == null || app.instrumentationClass == null) {
3112                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3113                mStackSupervisor.startHomeActivity(intent, aInfo);
3114            }
3115        }
3116
3117        return true;
3118    }
3119
3120    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3121        ActivityInfo ai = null;
3122        ComponentName comp = intent.getComponent();
3123        try {
3124            if (comp != null) {
3125                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3126            } else {
3127                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3128                        intent,
3129                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3130                            flags, userId);
3131
3132                if (info != null) {
3133                    ai = info.activityInfo;
3134                }
3135            }
3136        } catch (RemoteException e) {
3137            // ignore
3138        }
3139
3140        return ai;
3141    }
3142
3143    /**
3144     * Starts the "new version setup screen" if appropriate.
3145     */
3146    void startSetupActivityLocked() {
3147        // Only do this once per boot.
3148        if (mCheckedForSetup) {
3149            return;
3150        }
3151
3152        // We will show this screen if the current one is a different
3153        // version than the last one shown, and we are not running in
3154        // low-level factory test mode.
3155        final ContentResolver resolver = mContext.getContentResolver();
3156        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3157                Settings.Global.getInt(resolver,
3158                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3159            mCheckedForSetup = true;
3160
3161            // See if we should be showing the platform update setup UI.
3162            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3163            List<ResolveInfo> ris = mContext.getPackageManager()
3164                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3165
3166            // We don't allow third party apps to replace this.
3167            ResolveInfo ri = null;
3168            for (int i=0; ris != null && i<ris.size(); i++) {
3169                if ((ris.get(i).activityInfo.applicationInfo.flags
3170                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3171                    ri = ris.get(i);
3172                    break;
3173                }
3174            }
3175
3176            if (ri != null) {
3177                String vers = ri.activityInfo.metaData != null
3178                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3179                        : null;
3180                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3181                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3182                            Intent.METADATA_SETUP_VERSION);
3183                }
3184                String lastVers = Settings.Secure.getString(
3185                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3186                if (vers != null && !vers.equals(lastVers)) {
3187                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3188                    intent.setComponent(new ComponentName(
3189                            ri.activityInfo.packageName, ri.activityInfo.name));
3190                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3191                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3192                }
3193            }
3194        }
3195    }
3196
3197    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3198        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3199    }
3200
3201    void enforceNotIsolatedCaller(String caller) {
3202        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3203            throw new SecurityException("Isolated process not allowed to call " + caller);
3204        }
3205    }
3206
3207    @Override
3208    public int getFrontActivityScreenCompatMode() {
3209        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3210        synchronized (this) {
3211            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3212        }
3213    }
3214
3215    @Override
3216    public void setFrontActivityScreenCompatMode(int mode) {
3217        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3218                "setFrontActivityScreenCompatMode");
3219        synchronized (this) {
3220            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3221        }
3222    }
3223
3224    @Override
3225    public int getPackageScreenCompatMode(String packageName) {
3226        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3227        synchronized (this) {
3228            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3229        }
3230    }
3231
3232    @Override
3233    public void setPackageScreenCompatMode(String packageName, int mode) {
3234        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3235                "setPackageScreenCompatMode");
3236        synchronized (this) {
3237            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3238        }
3239    }
3240
3241    @Override
3242    public boolean getPackageAskScreenCompat(String packageName) {
3243        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3244        synchronized (this) {
3245            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3246        }
3247    }
3248
3249    @Override
3250    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3251        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3252                "setPackageAskScreenCompat");
3253        synchronized (this) {
3254            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3255        }
3256    }
3257
3258    private void dispatchProcessesChanged() {
3259        int N;
3260        synchronized (this) {
3261            N = mPendingProcessChanges.size();
3262            if (mActiveProcessChanges.length < N) {
3263                mActiveProcessChanges = new ProcessChangeItem[N];
3264            }
3265            mPendingProcessChanges.toArray(mActiveProcessChanges);
3266            mAvailProcessChanges.addAll(mPendingProcessChanges);
3267            mPendingProcessChanges.clear();
3268            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3269        }
3270
3271        int i = mProcessObservers.beginBroadcast();
3272        while (i > 0) {
3273            i--;
3274            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3275            if (observer != null) {
3276                try {
3277                    for (int j=0; j<N; j++) {
3278                        ProcessChangeItem item = mActiveProcessChanges[j];
3279                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3280                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3281                                    + item.pid + " uid=" + item.uid + ": "
3282                                    + item.foregroundActivities);
3283                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3284                                    item.foregroundActivities);
3285                        }
3286                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3287                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3288                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3289                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3290                        }
3291                    }
3292                } catch (RemoteException e) {
3293                }
3294            }
3295        }
3296        mProcessObservers.finishBroadcast();
3297    }
3298
3299    private void dispatchProcessDied(int pid, int uid) {
3300        int i = mProcessObservers.beginBroadcast();
3301        while (i > 0) {
3302            i--;
3303            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3304            if (observer != null) {
3305                try {
3306                    observer.onProcessDied(pid, uid);
3307                } catch (RemoteException e) {
3308                }
3309            }
3310        }
3311        mProcessObservers.finishBroadcast();
3312    }
3313
3314    final void doPendingActivityLaunchesLocked(boolean doResume) {
3315        final int N = mPendingActivityLaunches.size();
3316        if (N <= 0) {
3317            return;
3318        }
3319        for (int i=0; i<N; i++) {
3320            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3321            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3322                    doResume && i == (N-1), null);
3323        }
3324        mPendingActivityLaunches.clear();
3325    }
3326
3327    @Override
3328    public final int startActivity(IApplicationThread caller, String callingPackage,
3329            Intent intent, String resolvedType, IBinder resultTo,
3330            String resultWho, int requestCode, int startFlags,
3331            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3332        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3333                resultWho, requestCode,
3334                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3335    }
3336
3337    @Override
3338    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3339            Intent intent, String resolvedType, IBinder resultTo,
3340            String resultWho, int requestCode, int startFlags,
3341            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3342        enforceNotIsolatedCaller("startActivity");
3343        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3344                false, true, "startActivity", null);
3345        // TODO: Switch to user app stacks here.
3346        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3347                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3348                null, null, options, userId, null);
3349    }
3350
3351    @Override
3352    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3353            Intent intent, String resolvedType, IBinder resultTo,
3354            String resultWho, int requestCode, int startFlags, String profileFile,
3355            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3356        enforceNotIsolatedCaller("startActivityAndWait");
3357        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3358                false, true, "startActivityAndWait", null);
3359        WaitResult res = new WaitResult();
3360        // TODO: Switch to user app stacks here.
3361        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3362                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3363                res, null, options, UserHandle.getCallingUserId(), null);
3364        return res;
3365    }
3366
3367    @Override
3368    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3369            Intent intent, String resolvedType, IBinder resultTo,
3370            String resultWho, int requestCode, int startFlags, Configuration config,
3371            Bundle options, int userId) {
3372        enforceNotIsolatedCaller("startActivityWithConfig");
3373        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3374                false, true, "startActivityWithConfig", null);
3375        // TODO: Switch to user app stacks here.
3376        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3377                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3378                null, null, null, config, options, userId, null);
3379        return ret;
3380    }
3381
3382    @Override
3383    public int startActivityIntentSender(IApplicationThread caller,
3384            IntentSender intent, Intent fillInIntent, String resolvedType,
3385            IBinder resultTo, String resultWho, int requestCode,
3386            int flagsMask, int flagsValues, Bundle options) {
3387        enforceNotIsolatedCaller("startActivityIntentSender");
3388        // Refuse possible leaked file descriptors
3389        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3390            throw new IllegalArgumentException("File descriptors passed in Intent");
3391        }
3392
3393        IIntentSender sender = intent.getTarget();
3394        if (!(sender instanceof PendingIntentRecord)) {
3395            throw new IllegalArgumentException("Bad PendingIntent object");
3396        }
3397
3398        PendingIntentRecord pir = (PendingIntentRecord)sender;
3399
3400        synchronized (this) {
3401            // If this is coming from the currently resumed activity, it is
3402            // effectively saying that app switches are allowed at this point.
3403            final ActivityStack stack = getFocusedStack();
3404            if (stack.mResumedActivity != null &&
3405                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3406                mAppSwitchesAllowedTime = 0;
3407            }
3408        }
3409        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3410                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3411        return ret;
3412    }
3413
3414    @Override
3415    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3416            Intent intent, String resolvedType, IVoiceInteractionSession session,
3417            IVoiceInteractor interactor, int startFlags, String profileFile,
3418            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3419        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3420                != PackageManager.PERMISSION_GRANTED) {
3421            String msg = "Permission Denial: startVoiceActivity() from pid="
3422                    + Binder.getCallingPid()
3423                    + ", uid=" + Binder.getCallingUid()
3424                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3425            Slog.w(TAG, msg);
3426            throw new SecurityException(msg);
3427        }
3428        if (session == null || interactor == null) {
3429            throw new NullPointerException("null session or interactor");
3430        }
3431        userId = handleIncomingUser(callingPid, callingUid, userId,
3432                false, true, "startVoiceActivity", null);
3433        // TODO: Switch to user app stacks here.
3434        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3435                resolvedType, session, interactor, null, null, 0, startFlags,
3436                profileFile, profileFd, null, null, options, userId, null);
3437    }
3438
3439    @Override
3440    public boolean startNextMatchingActivity(IBinder callingActivity,
3441            Intent intent, Bundle options) {
3442        // Refuse possible leaked file descriptors
3443        if (intent != null && intent.hasFileDescriptors() == true) {
3444            throw new IllegalArgumentException("File descriptors passed in Intent");
3445        }
3446
3447        synchronized (this) {
3448            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3449            if (r == null) {
3450                ActivityOptions.abort(options);
3451                return false;
3452            }
3453            if (r.app == null || r.app.thread == null) {
3454                // The caller is not running...  d'oh!
3455                ActivityOptions.abort(options);
3456                return false;
3457            }
3458            intent = new Intent(intent);
3459            // The caller is not allowed to change the data.
3460            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3461            // And we are resetting to find the next component...
3462            intent.setComponent(null);
3463
3464            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3465
3466            ActivityInfo aInfo = null;
3467            try {
3468                List<ResolveInfo> resolves =
3469                    AppGlobals.getPackageManager().queryIntentActivities(
3470                            intent, r.resolvedType,
3471                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3472                            UserHandle.getCallingUserId());
3473
3474                // Look for the original activity in the list...
3475                final int N = resolves != null ? resolves.size() : 0;
3476                for (int i=0; i<N; i++) {
3477                    ResolveInfo rInfo = resolves.get(i);
3478                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3479                            && rInfo.activityInfo.name.equals(r.info.name)) {
3480                        // We found the current one...  the next matching is
3481                        // after it.
3482                        i++;
3483                        if (i<N) {
3484                            aInfo = resolves.get(i).activityInfo;
3485                        }
3486                        if (debug) {
3487                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3488                                    + "/" + r.info.name);
3489                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3490                                    + "/" + aInfo.name);
3491                        }
3492                        break;
3493                    }
3494                }
3495            } catch (RemoteException e) {
3496            }
3497
3498            if (aInfo == null) {
3499                // Nobody who is next!
3500                ActivityOptions.abort(options);
3501                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3502                return false;
3503            }
3504
3505            intent.setComponent(new ComponentName(
3506                    aInfo.applicationInfo.packageName, aInfo.name));
3507            intent.setFlags(intent.getFlags()&~(
3508                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3509                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3510                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3511                    Intent.FLAG_ACTIVITY_NEW_TASK));
3512
3513            // Okay now we need to start the new activity, replacing the
3514            // currently running activity.  This is a little tricky because
3515            // we want to start the new one as if the current one is finished,
3516            // but not finish the current one first so that there is no flicker.
3517            // And thus...
3518            final boolean wasFinishing = r.finishing;
3519            r.finishing = true;
3520
3521            // Propagate reply information over to the new activity.
3522            final ActivityRecord resultTo = r.resultTo;
3523            final String resultWho = r.resultWho;
3524            final int requestCode = r.requestCode;
3525            r.resultTo = null;
3526            if (resultTo != null) {
3527                resultTo.removeResultsLocked(r, resultWho, requestCode);
3528            }
3529
3530            final long origId = Binder.clearCallingIdentity();
3531            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3532                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3533                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3534                    options, false, null, null);
3535            Binder.restoreCallingIdentity(origId);
3536
3537            r.finishing = wasFinishing;
3538            if (res != ActivityManager.START_SUCCESS) {
3539                return false;
3540            }
3541            return true;
3542        }
3543    }
3544
3545    final int startActivityInPackage(int uid, String callingPackage,
3546            Intent intent, String resolvedType, IBinder resultTo,
3547            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3548                    IActivityContainer container) {
3549
3550        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3551                false, true, "startActivityInPackage", null);
3552
3553        // TODO: Switch to user app stacks here.
3554        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3555                null, null, resultTo, resultWho, requestCode, startFlags,
3556                null, null, null, null, options, userId, container);
3557        return ret;
3558    }
3559
3560    @Override
3561    public final int startActivities(IApplicationThread caller, String callingPackage,
3562            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3563            int userId) {
3564        enforceNotIsolatedCaller("startActivities");
3565        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3566                false, true, "startActivity", null);
3567        // TODO: Switch to user app stacks here.
3568        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3569                resolvedTypes, resultTo, options, userId);
3570        return ret;
3571    }
3572
3573    final int startActivitiesInPackage(int uid, String callingPackage,
3574            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3575            Bundle options, int userId) {
3576
3577        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3578                false, true, "startActivityInPackage", null);
3579        // TODO: Switch to user app stacks here.
3580        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3581                resultTo, options, userId);
3582        return ret;
3583    }
3584
3585    final void addRecentTaskLocked(TaskRecord task) {
3586        int N = mRecentTasks.size();
3587        // Quick case: check if the top-most recent task is the same.
3588        if (N > 0 && mRecentTasks.get(0) == task) {
3589            return;
3590        }
3591        // Another quick case: never add voice sessions.
3592        if (task.voiceSession != null) {
3593            return;
3594        }
3595        // Remove any existing entries that are the same kind of task.
3596        final Intent intent = task.intent;
3597        final boolean document = intent != null && intent.isDocument();
3598        final ComponentName comp = intent.getComponent();
3599
3600        int maxRecents = task.maxRecents - 1;
3601        for (int i=0; i<N; i++) {
3602            TaskRecord tr = mRecentTasks.get(i);
3603            if (task != tr) {
3604                if (task.userId != tr.userId) {
3605                    continue;
3606                }
3607                if (i > MAX_RECENT_BITMAPS) {
3608                    tr.freeLastThumbnail();
3609                }
3610                final Intent trIntent = tr.intent;
3611                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3612                    (intent == null || !intent.filterEquals(trIntent))) {
3613                    continue;
3614                }
3615                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3616                if (document && trIsDocument) {
3617                    // These are the same document activity (not necessarily the same doc).
3618                    if (maxRecents > 0) {
3619                        --maxRecents;
3620                        continue;
3621                    }
3622                    // Hit the maximum number of documents for this task. Fall through
3623                    // and remove this document from recents.
3624                } else if (document || trIsDocument) {
3625                    // Only one of these is a document. Not the droid we're looking for.
3626                    continue;
3627                }
3628            }
3629
3630            // Either task and tr are the same or, their affinities match or their intents match
3631            // and neither of them is a document, or they are documents using the same activity
3632            // and their maxRecents has been reached.
3633            tr.disposeThumbnail();
3634            mRecentTasks.remove(i);
3635            i--;
3636            N--;
3637            if (task.intent == null) {
3638                // If the new recent task we are adding is not fully
3639                // specified, then replace it with the existing recent task.
3640                task = tr;
3641            }
3642            mTaskPersister.notify(tr, false);
3643        }
3644        if (N >= MAX_RECENT_TASKS) {
3645            mRecentTasks.remove(N-1).disposeThumbnail();
3646        }
3647        mRecentTasks.add(0, task);
3648    }
3649
3650    @Override
3651    public void reportActivityFullyDrawn(IBinder token) {
3652        synchronized (this) {
3653            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3654            if (r == null) {
3655                return;
3656            }
3657            r.reportFullyDrawnLocked();
3658        }
3659    }
3660
3661    @Override
3662    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3663        synchronized (this) {
3664            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3665            if (r == null) {
3666                return;
3667            }
3668            final long origId = Binder.clearCallingIdentity();
3669            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3670            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3671                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3672            if (config != null) {
3673                r.frozenBeforeDestroy = true;
3674                if (!updateConfigurationLocked(config, r, false, false)) {
3675                    mStackSupervisor.resumeTopActivitiesLocked();
3676                }
3677            }
3678            Binder.restoreCallingIdentity(origId);
3679        }
3680    }
3681
3682    @Override
3683    public int getRequestedOrientation(IBinder token) {
3684        synchronized (this) {
3685            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3686            if (r == null) {
3687                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3688            }
3689            return mWindowManager.getAppOrientation(r.appToken);
3690        }
3691    }
3692
3693    /**
3694     * This is the internal entry point for handling Activity.finish().
3695     *
3696     * @param token The Binder token referencing the Activity we want to finish.
3697     * @param resultCode Result code, if any, from this Activity.
3698     * @param resultData Result data (Intent), if any, from this Activity.
3699     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3700     *            the root Activity in the task.
3701     *
3702     * @return Returns true if the activity successfully finished, or false if it is still running.
3703     */
3704    @Override
3705    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3706            boolean finishTask) {
3707        // Refuse possible leaked file descriptors
3708        if (resultData != null && resultData.hasFileDescriptors() == true) {
3709            throw new IllegalArgumentException("File descriptors passed in Intent");
3710        }
3711
3712        synchronized(this) {
3713            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3714            if (r == null) {
3715                return true;
3716            }
3717            // Keep track of the root activity of the task before we finish it
3718            TaskRecord tr = r.task;
3719            ActivityRecord rootR = tr.getRootActivity();
3720            // Do not allow task to finish in Lock Task mode.
3721            if (tr == mStackSupervisor.mLockTaskModeTask) {
3722                if (rootR == r) {
3723                    return false;
3724                }
3725            }
3726            if (mController != null) {
3727                // Find the first activity that is not finishing.
3728                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3729                if (next != null) {
3730                    // ask watcher if this is allowed
3731                    boolean resumeOK = true;
3732                    try {
3733                        resumeOK = mController.activityResuming(next.packageName);
3734                    } catch (RemoteException e) {
3735                        mController = null;
3736                        Watchdog.getInstance().setActivityController(null);
3737                    }
3738
3739                    if (!resumeOK) {
3740                        return false;
3741                    }
3742                }
3743            }
3744            final long origId = Binder.clearCallingIdentity();
3745            try {
3746                boolean res;
3747                if (finishTask && r == rootR) {
3748                    // If requested, remove the task that is associated to this activity only if it
3749                    // was the root activity in the task.  The result code and data is ignored because
3750                    // we don't support returning them across task boundaries.
3751                    res = removeTaskByIdLocked(tr.taskId, 0);
3752                } else {
3753                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3754                            resultData, "app-request", true);
3755                }
3756                return res;
3757            } finally {
3758                Binder.restoreCallingIdentity(origId);
3759            }
3760        }
3761    }
3762
3763    @Override
3764    public final void finishHeavyWeightApp() {
3765        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3766                != PackageManager.PERMISSION_GRANTED) {
3767            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3768                    + Binder.getCallingPid()
3769                    + ", uid=" + Binder.getCallingUid()
3770                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3771            Slog.w(TAG, msg);
3772            throw new SecurityException(msg);
3773        }
3774
3775        synchronized(this) {
3776            if (mHeavyWeightProcess == null) {
3777                return;
3778            }
3779
3780            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3781                    mHeavyWeightProcess.activities);
3782            for (int i=0; i<activities.size(); i++) {
3783                ActivityRecord r = activities.get(i);
3784                if (!r.finishing) {
3785                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3786                            null, "finish-heavy", true);
3787                }
3788            }
3789
3790            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3791                    mHeavyWeightProcess.userId, 0));
3792            mHeavyWeightProcess = null;
3793        }
3794    }
3795
3796    @Override
3797    public void crashApplication(int uid, int initialPid, String packageName,
3798            String message) {
3799        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3800                != PackageManager.PERMISSION_GRANTED) {
3801            String msg = "Permission Denial: crashApplication() from pid="
3802                    + Binder.getCallingPid()
3803                    + ", uid=" + Binder.getCallingUid()
3804                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3805            Slog.w(TAG, msg);
3806            throw new SecurityException(msg);
3807        }
3808
3809        synchronized(this) {
3810            ProcessRecord proc = null;
3811
3812            // Figure out which process to kill.  We don't trust that initialPid
3813            // still has any relation to current pids, so must scan through the
3814            // list.
3815            synchronized (mPidsSelfLocked) {
3816                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3817                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3818                    if (p.uid != uid) {
3819                        continue;
3820                    }
3821                    if (p.pid == initialPid) {
3822                        proc = p;
3823                        break;
3824                    }
3825                    if (p.pkgList.containsKey(packageName)) {
3826                        proc = p;
3827                    }
3828                }
3829            }
3830
3831            if (proc == null) {
3832                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3833                        + " initialPid=" + initialPid
3834                        + " packageName=" + packageName);
3835                return;
3836            }
3837
3838            if (proc.thread != null) {
3839                if (proc.pid == Process.myPid()) {
3840                    Log.w(TAG, "crashApplication: trying to crash self!");
3841                    return;
3842                }
3843                long ident = Binder.clearCallingIdentity();
3844                try {
3845                    proc.thread.scheduleCrash(message);
3846                } catch (RemoteException e) {
3847                }
3848                Binder.restoreCallingIdentity(ident);
3849            }
3850        }
3851    }
3852
3853    @Override
3854    public final void finishSubActivity(IBinder token, String resultWho,
3855            int requestCode) {
3856        synchronized(this) {
3857            final long origId = Binder.clearCallingIdentity();
3858            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3859            if (r != null) {
3860                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3861            }
3862            Binder.restoreCallingIdentity(origId);
3863        }
3864    }
3865
3866    @Override
3867    public boolean finishActivityAffinity(IBinder token) {
3868        synchronized(this) {
3869            final long origId = Binder.clearCallingIdentity();
3870            try {
3871                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3872
3873                ActivityRecord rootR = r.task.getRootActivity();
3874                // Do not allow task to finish in Lock Task mode.
3875                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3876                    if (rootR == r) {
3877                        Binder.restoreCallingIdentity(origId);
3878                        return false;
3879                    }
3880                }
3881                boolean res = false;
3882                if (r != null) {
3883                    res = r.task.stack.finishActivityAffinityLocked(r);
3884                }
3885                return res;
3886            } finally {
3887                Binder.restoreCallingIdentity(origId);
3888            }
3889        }
3890    }
3891
3892    @Override
3893    public boolean willActivityBeVisible(IBinder token) {
3894        synchronized(this) {
3895            ActivityStack stack = ActivityRecord.getStackLocked(token);
3896            if (stack != null) {
3897                return stack.willActivityBeVisibleLocked(token);
3898            }
3899            return false;
3900        }
3901    }
3902
3903    @Override
3904    public void overridePendingTransition(IBinder token, String packageName,
3905            int enterAnim, int exitAnim) {
3906        synchronized(this) {
3907            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3908            if (self == null) {
3909                return;
3910            }
3911
3912            final long origId = Binder.clearCallingIdentity();
3913
3914            if (self.state == ActivityState.RESUMED
3915                    || self.state == ActivityState.PAUSING) {
3916                mWindowManager.overridePendingAppTransition(packageName,
3917                        enterAnim, exitAnim, null);
3918            }
3919
3920            Binder.restoreCallingIdentity(origId);
3921        }
3922    }
3923
3924    /**
3925     * Main function for removing an existing process from the activity manager
3926     * as a result of that process going away.  Clears out all connections
3927     * to the process.
3928     */
3929    private final void handleAppDiedLocked(ProcessRecord app,
3930            boolean restarting, boolean allowRestart) {
3931        int pid = app.pid;
3932        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3933        if (!restarting) {
3934            removeLruProcessLocked(app);
3935            if (pid > 0) {
3936                ProcessList.remove(pid);
3937            }
3938        }
3939
3940        if (mProfileProc == app) {
3941            clearProfilerLocked();
3942        }
3943
3944        // Remove this application's activities from active lists.
3945        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3946
3947        app.activities.clear();
3948
3949        if (app.instrumentationClass != null) {
3950            Slog.w(TAG, "Crash of app " + app.processName
3951                  + " running instrumentation " + app.instrumentationClass);
3952            Bundle info = new Bundle();
3953            info.putString("shortMsg", "Process crashed.");
3954            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3955        }
3956
3957        if (!restarting) {
3958            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3959                // If there was nothing to resume, and we are not already
3960                // restarting this process, but there is a visible activity that
3961                // is hosted by the process...  then make sure all visible
3962                // activities are running, taking care of restarting this
3963                // process.
3964                if (hasVisibleActivities) {
3965                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3966                }
3967            }
3968        }
3969    }
3970
3971    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3972        IBinder threadBinder = thread.asBinder();
3973        // Find the application record.
3974        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3975            ProcessRecord rec = mLruProcesses.get(i);
3976            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3977                return i;
3978            }
3979        }
3980        return -1;
3981    }
3982
3983    final ProcessRecord getRecordForAppLocked(
3984            IApplicationThread thread) {
3985        if (thread == null) {
3986            return null;
3987        }
3988
3989        int appIndex = getLRURecordIndexForAppLocked(thread);
3990        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3991    }
3992
3993    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3994        // If there are no longer any background processes running,
3995        // and the app that died was not running instrumentation,
3996        // then tell everyone we are now low on memory.
3997        boolean haveBg = false;
3998        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3999            ProcessRecord rec = mLruProcesses.get(i);
4000            if (rec.thread != null
4001                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4002                haveBg = true;
4003                break;
4004            }
4005        }
4006
4007        if (!haveBg) {
4008            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4009            if (doReport) {
4010                long now = SystemClock.uptimeMillis();
4011                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4012                    doReport = false;
4013                } else {
4014                    mLastMemUsageReportTime = now;
4015                }
4016            }
4017            final ArrayList<ProcessMemInfo> memInfos
4018                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4019            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4020            long now = SystemClock.uptimeMillis();
4021            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4022                ProcessRecord rec = mLruProcesses.get(i);
4023                if (rec == dyingProc || rec.thread == null) {
4024                    continue;
4025                }
4026                if (doReport) {
4027                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4028                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4029                }
4030                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4031                    // The low memory report is overriding any current
4032                    // state for a GC request.  Make sure to do
4033                    // heavy/important/visible/foreground processes first.
4034                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4035                        rec.lastRequestedGc = 0;
4036                    } else {
4037                        rec.lastRequestedGc = rec.lastLowMemory;
4038                    }
4039                    rec.reportLowMemory = true;
4040                    rec.lastLowMemory = now;
4041                    mProcessesToGc.remove(rec);
4042                    addProcessToGcListLocked(rec);
4043                }
4044            }
4045            if (doReport) {
4046                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4047                mHandler.sendMessage(msg);
4048            }
4049            scheduleAppGcsLocked();
4050        }
4051    }
4052
4053    final void appDiedLocked(ProcessRecord app, int pid,
4054            IApplicationThread thread) {
4055
4056        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4057        synchronized (stats) {
4058            stats.noteProcessDiedLocked(app.info.uid, pid);
4059        }
4060
4061        // Clean up already done if the process has been re-started.
4062        if (app.pid == pid && app.thread != null &&
4063                app.thread.asBinder() == thread.asBinder()) {
4064            boolean doLowMem = app.instrumentationClass == null;
4065            boolean doOomAdj = doLowMem;
4066            if (!app.killedByAm) {
4067                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4068                        + ") has died.");
4069                mAllowLowerMemLevel = true;
4070            } else {
4071                // Note that we always want to do oom adj to update our state with the
4072                // new number of procs.
4073                mAllowLowerMemLevel = false;
4074                doLowMem = false;
4075            }
4076            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4077            if (DEBUG_CLEANUP) Slog.v(
4078                TAG, "Dying app: " + app + ", pid: " + pid
4079                + ", thread: " + thread.asBinder());
4080            handleAppDiedLocked(app, false, true);
4081
4082            if (doOomAdj) {
4083                updateOomAdjLocked();
4084            }
4085            if (doLowMem) {
4086                doLowMemReportIfNeededLocked(app);
4087            }
4088        } else if (app.pid != pid) {
4089            // A new process has already been started.
4090            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4091                    + ") has died and restarted (pid " + app.pid + ").");
4092            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4093        } else if (DEBUG_PROCESSES) {
4094            Slog.d(TAG, "Received spurious death notification for thread "
4095                    + thread.asBinder());
4096        }
4097    }
4098
4099    /**
4100     * If a stack trace dump file is configured, dump process stack traces.
4101     * @param clearTraces causes the dump file to be erased prior to the new
4102     *    traces being written, if true; when false, the new traces will be
4103     *    appended to any existing file content.
4104     * @param firstPids of dalvik VM processes to dump stack traces for first
4105     * @param lastPids of dalvik VM processes to dump stack traces for last
4106     * @param nativeProcs optional list of native process names to dump stack crawls
4107     * @return file containing stack traces, or null if no dump file is configured
4108     */
4109    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4110            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4111        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4112        if (tracesPath == null || tracesPath.length() == 0) {
4113            return null;
4114        }
4115
4116        File tracesFile = new File(tracesPath);
4117        try {
4118            File tracesDir = tracesFile.getParentFile();
4119            if (!tracesDir.exists()) {
4120                tracesFile.mkdirs();
4121                if (!SELinux.restorecon(tracesDir)) {
4122                    return null;
4123                }
4124            }
4125            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4126
4127            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4128            tracesFile.createNewFile();
4129            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4130        } catch (IOException e) {
4131            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4132            return null;
4133        }
4134
4135        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4136        return tracesFile;
4137    }
4138
4139    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4140            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4141        // Use a FileObserver to detect when traces finish writing.
4142        // The order of traces is considered important to maintain for legibility.
4143        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4144            @Override
4145            public synchronized void onEvent(int event, String path) { notify(); }
4146        };
4147
4148        try {
4149            observer.startWatching();
4150
4151            // First collect all of the stacks of the most important pids.
4152            if (firstPids != null) {
4153                try {
4154                    int num = firstPids.size();
4155                    for (int i = 0; i < num; i++) {
4156                        synchronized (observer) {
4157                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4158                            observer.wait(200);  // Wait for write-close, give up after 200msec
4159                        }
4160                    }
4161                } catch (InterruptedException e) {
4162                    Log.wtf(TAG, e);
4163                }
4164            }
4165
4166            // Next collect the stacks of the native pids
4167            if (nativeProcs != null) {
4168                int[] pids = Process.getPidsForCommands(nativeProcs);
4169                if (pids != null) {
4170                    for (int pid : pids) {
4171                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4172                    }
4173                }
4174            }
4175
4176            // Lastly, measure CPU usage.
4177            if (processCpuTracker != null) {
4178                processCpuTracker.init();
4179                System.gc();
4180                processCpuTracker.update();
4181                try {
4182                    synchronized (processCpuTracker) {
4183                        processCpuTracker.wait(500); // measure over 1/2 second.
4184                    }
4185                } catch (InterruptedException e) {
4186                }
4187                processCpuTracker.update();
4188
4189                // We'll take the stack crawls of just the top apps using CPU.
4190                final int N = processCpuTracker.countWorkingStats();
4191                int numProcs = 0;
4192                for (int i=0; i<N && numProcs<5; i++) {
4193                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4194                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4195                        numProcs++;
4196                        try {
4197                            synchronized (observer) {
4198                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4199                                observer.wait(200);  // Wait for write-close, give up after 200msec
4200                            }
4201                        } catch (InterruptedException e) {
4202                            Log.wtf(TAG, e);
4203                        }
4204
4205                    }
4206                }
4207            }
4208        } finally {
4209            observer.stopWatching();
4210        }
4211    }
4212
4213    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4214        if (true || IS_USER_BUILD) {
4215            return;
4216        }
4217        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4218        if (tracesPath == null || tracesPath.length() == 0) {
4219            return;
4220        }
4221
4222        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4223        StrictMode.allowThreadDiskWrites();
4224        try {
4225            final File tracesFile = new File(tracesPath);
4226            final File tracesDir = tracesFile.getParentFile();
4227            final File tracesTmp = new File(tracesDir, "__tmp__");
4228            try {
4229                if (!tracesDir.exists()) {
4230                    tracesFile.mkdirs();
4231                    if (!SELinux.restorecon(tracesDir.getPath())) {
4232                        return;
4233                    }
4234                }
4235                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4236
4237                if (tracesFile.exists()) {
4238                    tracesTmp.delete();
4239                    tracesFile.renameTo(tracesTmp);
4240                }
4241                StringBuilder sb = new StringBuilder();
4242                Time tobj = new Time();
4243                tobj.set(System.currentTimeMillis());
4244                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4245                sb.append(": ");
4246                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4247                sb.append(" since ");
4248                sb.append(msg);
4249                FileOutputStream fos = new FileOutputStream(tracesFile);
4250                fos.write(sb.toString().getBytes());
4251                if (app == null) {
4252                    fos.write("\n*** No application process!".getBytes());
4253                }
4254                fos.close();
4255                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4256            } catch (IOException e) {
4257                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4258                return;
4259            }
4260
4261            if (app != null) {
4262                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4263                firstPids.add(app.pid);
4264                dumpStackTraces(tracesPath, firstPids, null, null, null);
4265            }
4266
4267            File lastTracesFile = null;
4268            File curTracesFile = null;
4269            for (int i=9; i>=0; i--) {
4270                String name = String.format(Locale.US, "slow%02d.txt", i);
4271                curTracesFile = new File(tracesDir, name);
4272                if (curTracesFile.exists()) {
4273                    if (lastTracesFile != null) {
4274                        curTracesFile.renameTo(lastTracesFile);
4275                    } else {
4276                        curTracesFile.delete();
4277                    }
4278                }
4279                lastTracesFile = curTracesFile;
4280            }
4281            tracesFile.renameTo(curTracesFile);
4282            if (tracesTmp.exists()) {
4283                tracesTmp.renameTo(tracesFile);
4284            }
4285        } finally {
4286            StrictMode.setThreadPolicy(oldPolicy);
4287        }
4288    }
4289
4290    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4291            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4292        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4293        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4294
4295        if (mController != null) {
4296            try {
4297                // 0 == continue, -1 = kill process immediately
4298                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4299                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4300            } catch (RemoteException e) {
4301                mController = null;
4302                Watchdog.getInstance().setActivityController(null);
4303            }
4304        }
4305
4306        long anrTime = SystemClock.uptimeMillis();
4307        if (MONITOR_CPU_USAGE) {
4308            updateCpuStatsNow();
4309        }
4310
4311        synchronized (this) {
4312            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4313            if (mShuttingDown) {
4314                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4315                return;
4316            } else if (app.notResponding) {
4317                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4318                return;
4319            } else if (app.crashing) {
4320                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4321                return;
4322            }
4323
4324            // In case we come through here for the same app before completing
4325            // this one, mark as anring now so we will bail out.
4326            app.notResponding = true;
4327
4328            // Log the ANR to the event log.
4329            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4330                    app.processName, app.info.flags, annotation);
4331
4332            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4333            firstPids.add(app.pid);
4334
4335            int parentPid = app.pid;
4336            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4337            if (parentPid != app.pid) firstPids.add(parentPid);
4338
4339            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4340
4341            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4342                ProcessRecord r = mLruProcesses.get(i);
4343                if (r != null && r.thread != null) {
4344                    int pid = r.pid;
4345                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4346                        if (r.persistent) {
4347                            firstPids.add(pid);
4348                        } else {
4349                            lastPids.put(pid, Boolean.TRUE);
4350                        }
4351                    }
4352                }
4353            }
4354        }
4355
4356        // Log the ANR to the main log.
4357        StringBuilder info = new StringBuilder();
4358        info.setLength(0);
4359        info.append("ANR in ").append(app.processName);
4360        if (activity != null && activity.shortComponentName != null) {
4361            info.append(" (").append(activity.shortComponentName).append(")");
4362        }
4363        info.append("\n");
4364        info.append("PID: ").append(app.pid).append("\n");
4365        if (annotation != null) {
4366            info.append("Reason: ").append(annotation).append("\n");
4367        }
4368        if (parent != null && parent != activity) {
4369            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4370        }
4371
4372        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4373
4374        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4375                NATIVE_STACKS_OF_INTEREST);
4376
4377        String cpuInfo = null;
4378        if (MONITOR_CPU_USAGE) {
4379            updateCpuStatsNow();
4380            synchronized (mProcessCpuThread) {
4381                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4382            }
4383            info.append(processCpuTracker.printCurrentLoad());
4384            info.append(cpuInfo);
4385        }
4386
4387        info.append(processCpuTracker.printCurrentState(anrTime));
4388
4389        Slog.e(TAG, info.toString());
4390        if (tracesFile == null) {
4391            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4392            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4393        }
4394
4395        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4396                cpuInfo, tracesFile, null);
4397
4398        if (mController != null) {
4399            try {
4400                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4401                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4402                if (res != 0) {
4403                    if (res < 0 && app.pid != MY_PID) {
4404                        Process.killProcess(app.pid);
4405                    } else {
4406                        synchronized (this) {
4407                            mServices.scheduleServiceTimeoutLocked(app);
4408                        }
4409                    }
4410                    return;
4411                }
4412            } catch (RemoteException e) {
4413                mController = null;
4414                Watchdog.getInstance().setActivityController(null);
4415            }
4416        }
4417
4418        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4419        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4420                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4421
4422        synchronized (this) {
4423            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4424                killUnneededProcessLocked(app, "background ANR");
4425                return;
4426            }
4427
4428            // Set the app's notResponding state, and look up the errorReportReceiver
4429            makeAppNotRespondingLocked(app,
4430                    activity != null ? activity.shortComponentName : null,
4431                    annotation != null ? "ANR " + annotation : "ANR",
4432                    info.toString());
4433
4434            // Bring up the infamous App Not Responding dialog
4435            Message msg = Message.obtain();
4436            HashMap<String, Object> map = new HashMap<String, Object>();
4437            msg.what = SHOW_NOT_RESPONDING_MSG;
4438            msg.obj = map;
4439            msg.arg1 = aboveSystem ? 1 : 0;
4440            map.put("app", app);
4441            if (activity != null) {
4442                map.put("activity", activity);
4443            }
4444
4445            mHandler.sendMessage(msg);
4446        }
4447    }
4448
4449    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4450        if (!mLaunchWarningShown) {
4451            mLaunchWarningShown = true;
4452            mHandler.post(new Runnable() {
4453                @Override
4454                public void run() {
4455                    synchronized (ActivityManagerService.this) {
4456                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4457                        d.show();
4458                        mHandler.postDelayed(new Runnable() {
4459                            @Override
4460                            public void run() {
4461                                synchronized (ActivityManagerService.this) {
4462                                    d.dismiss();
4463                                    mLaunchWarningShown = false;
4464                                }
4465                            }
4466                        }, 4000);
4467                    }
4468                }
4469            });
4470        }
4471    }
4472
4473    @Override
4474    public boolean clearApplicationUserData(final String packageName,
4475            final IPackageDataObserver observer, int userId) {
4476        enforceNotIsolatedCaller("clearApplicationUserData");
4477        int uid = Binder.getCallingUid();
4478        int pid = Binder.getCallingPid();
4479        userId = handleIncomingUser(pid, uid,
4480                userId, false, true, "clearApplicationUserData", null);
4481        long callingId = Binder.clearCallingIdentity();
4482        try {
4483            IPackageManager pm = AppGlobals.getPackageManager();
4484            int pkgUid = -1;
4485            synchronized(this) {
4486                try {
4487                    pkgUid = pm.getPackageUid(packageName, userId);
4488                } catch (RemoteException e) {
4489                }
4490                if (pkgUid == -1) {
4491                    Slog.w(TAG, "Invalid packageName: " + packageName);
4492                    if (observer != null) {
4493                        try {
4494                            observer.onRemoveCompleted(packageName, false);
4495                        } catch (RemoteException e) {
4496                            Slog.i(TAG, "Observer no longer exists.");
4497                        }
4498                    }
4499                    return false;
4500                }
4501                if (uid == pkgUid || checkComponentPermission(
4502                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4503                        pid, uid, -1, true)
4504                        == PackageManager.PERMISSION_GRANTED) {
4505                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4506                } else {
4507                    throw new SecurityException("PID " + pid + " does not have permission "
4508                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4509                                    + " of package " + packageName);
4510                }
4511            }
4512
4513            try {
4514                // Clear application user data
4515                pm.clearApplicationUserData(packageName, observer, userId);
4516
4517                // Remove all permissions granted from/to this package
4518                removeUriPermissionsForPackageLocked(packageName, userId, true);
4519
4520                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4521                        Uri.fromParts("package", packageName, null));
4522                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4523                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4524                        null, null, 0, null, null, null, false, false, userId);
4525            } catch (RemoteException e) {
4526            }
4527        } finally {
4528            Binder.restoreCallingIdentity(callingId);
4529        }
4530        return true;
4531    }
4532
4533    @Override
4534    public void killBackgroundProcesses(final String packageName, int userId) {
4535        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4536                != PackageManager.PERMISSION_GRANTED &&
4537                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4538                        != PackageManager.PERMISSION_GRANTED) {
4539            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4540                    + Binder.getCallingPid()
4541                    + ", uid=" + Binder.getCallingUid()
4542                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4543            Slog.w(TAG, msg);
4544            throw new SecurityException(msg);
4545        }
4546
4547        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4548                userId, true, true, "killBackgroundProcesses", null);
4549        long callingId = Binder.clearCallingIdentity();
4550        try {
4551            IPackageManager pm = AppGlobals.getPackageManager();
4552            synchronized(this) {
4553                int appId = -1;
4554                try {
4555                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4556                } catch (RemoteException e) {
4557                }
4558                if (appId == -1) {
4559                    Slog.w(TAG, "Invalid packageName: " + packageName);
4560                    return;
4561                }
4562                killPackageProcessesLocked(packageName, appId, userId,
4563                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4564            }
4565        } finally {
4566            Binder.restoreCallingIdentity(callingId);
4567        }
4568    }
4569
4570    @Override
4571    public void killAllBackgroundProcesses() {
4572        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4573                != PackageManager.PERMISSION_GRANTED) {
4574            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4575                    + Binder.getCallingPid()
4576                    + ", uid=" + Binder.getCallingUid()
4577                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4578            Slog.w(TAG, msg);
4579            throw new SecurityException(msg);
4580        }
4581
4582        long callingId = Binder.clearCallingIdentity();
4583        try {
4584            synchronized(this) {
4585                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4586                final int NP = mProcessNames.getMap().size();
4587                for (int ip=0; ip<NP; ip++) {
4588                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4589                    final int NA = apps.size();
4590                    for (int ia=0; ia<NA; ia++) {
4591                        ProcessRecord app = apps.valueAt(ia);
4592                        if (app.persistent) {
4593                            // we don't kill persistent processes
4594                            continue;
4595                        }
4596                        if (app.removed) {
4597                            procs.add(app);
4598                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4599                            app.removed = true;
4600                            procs.add(app);
4601                        }
4602                    }
4603                }
4604
4605                int N = procs.size();
4606                for (int i=0; i<N; i++) {
4607                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4608                }
4609                mAllowLowerMemLevel = true;
4610                updateOomAdjLocked();
4611                doLowMemReportIfNeededLocked(null);
4612            }
4613        } finally {
4614            Binder.restoreCallingIdentity(callingId);
4615        }
4616    }
4617
4618    @Override
4619    public void forceStopPackage(final String packageName, int userId) {
4620        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4621                != PackageManager.PERMISSION_GRANTED) {
4622            String msg = "Permission Denial: forceStopPackage() from pid="
4623                    + Binder.getCallingPid()
4624                    + ", uid=" + Binder.getCallingUid()
4625                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4626            Slog.w(TAG, msg);
4627            throw new SecurityException(msg);
4628        }
4629        final int callingPid = Binder.getCallingPid();
4630        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4631                userId, true, true, "forceStopPackage", null);
4632        long callingId = Binder.clearCallingIdentity();
4633        try {
4634            IPackageManager pm = AppGlobals.getPackageManager();
4635            synchronized(this) {
4636                int[] users = userId == UserHandle.USER_ALL
4637                        ? getUsersLocked() : new int[] { userId };
4638                for (int user : users) {
4639                    int pkgUid = -1;
4640                    try {
4641                        pkgUid = pm.getPackageUid(packageName, user);
4642                    } catch (RemoteException e) {
4643                    }
4644                    if (pkgUid == -1) {
4645                        Slog.w(TAG, "Invalid packageName: " + packageName);
4646                        continue;
4647                    }
4648                    try {
4649                        pm.setPackageStoppedState(packageName, true, user);
4650                    } catch (RemoteException e) {
4651                    } catch (IllegalArgumentException e) {
4652                        Slog.w(TAG, "Failed trying to unstop package "
4653                                + packageName + ": " + e);
4654                    }
4655                    if (isUserRunningLocked(user, false)) {
4656                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4657                    }
4658                }
4659            }
4660        } finally {
4661            Binder.restoreCallingIdentity(callingId);
4662        }
4663    }
4664
4665    /*
4666     * The pkg name and app id have to be specified.
4667     */
4668    @Override
4669    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4670        if (pkg == null) {
4671            return;
4672        }
4673        // Make sure the uid is valid.
4674        if (appid < 0) {
4675            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4676            return;
4677        }
4678        int callerUid = Binder.getCallingUid();
4679        // Only the system server can kill an application
4680        if (callerUid == Process.SYSTEM_UID) {
4681            // Post an aysnc message to kill the application
4682            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4683            msg.arg1 = appid;
4684            msg.arg2 = 0;
4685            Bundle bundle = new Bundle();
4686            bundle.putString("pkg", pkg);
4687            bundle.putString("reason", reason);
4688            msg.obj = bundle;
4689            mHandler.sendMessage(msg);
4690        } else {
4691            throw new SecurityException(callerUid + " cannot kill pkg: " +
4692                    pkg);
4693        }
4694    }
4695
4696    @Override
4697    public void closeSystemDialogs(String reason) {
4698        enforceNotIsolatedCaller("closeSystemDialogs");
4699
4700        final int pid = Binder.getCallingPid();
4701        final int uid = Binder.getCallingUid();
4702        final long origId = Binder.clearCallingIdentity();
4703        try {
4704            synchronized (this) {
4705                // Only allow this from foreground processes, so that background
4706                // applications can't abuse it to prevent system UI from being shown.
4707                if (uid >= Process.FIRST_APPLICATION_UID) {
4708                    ProcessRecord proc;
4709                    synchronized (mPidsSelfLocked) {
4710                        proc = mPidsSelfLocked.get(pid);
4711                    }
4712                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4713                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4714                                + " from background process " + proc);
4715                        return;
4716                    }
4717                }
4718                closeSystemDialogsLocked(reason);
4719            }
4720        } finally {
4721            Binder.restoreCallingIdentity(origId);
4722        }
4723    }
4724
4725    void closeSystemDialogsLocked(String reason) {
4726        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4727        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4728                | Intent.FLAG_RECEIVER_FOREGROUND);
4729        if (reason != null) {
4730            intent.putExtra("reason", reason);
4731        }
4732        mWindowManager.closeSystemDialogs(reason);
4733
4734        mStackSupervisor.closeSystemDialogsLocked();
4735
4736        broadcastIntentLocked(null, null, intent, null,
4737                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4738                Process.SYSTEM_UID, UserHandle.USER_ALL);
4739    }
4740
4741    @Override
4742    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4743        enforceNotIsolatedCaller("getProcessMemoryInfo");
4744        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4745        for (int i=pids.length-1; i>=0; i--) {
4746            ProcessRecord proc;
4747            int oomAdj;
4748            synchronized (this) {
4749                synchronized (mPidsSelfLocked) {
4750                    proc = mPidsSelfLocked.get(pids[i]);
4751                    oomAdj = proc != null ? proc.setAdj : 0;
4752                }
4753            }
4754            infos[i] = new Debug.MemoryInfo();
4755            Debug.getMemoryInfo(pids[i], infos[i]);
4756            if (proc != null) {
4757                synchronized (this) {
4758                    if (proc.thread != null && proc.setAdj == oomAdj) {
4759                        // Record this for posterity if the process has been stable.
4760                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4761                                infos[i].getTotalUss(), false, proc.pkgList);
4762                    }
4763                }
4764            }
4765        }
4766        return infos;
4767    }
4768
4769    @Override
4770    public long[] getProcessPss(int[] pids) {
4771        enforceNotIsolatedCaller("getProcessPss");
4772        long[] pss = new long[pids.length];
4773        for (int i=pids.length-1; i>=0; i--) {
4774            ProcessRecord proc;
4775            int oomAdj;
4776            synchronized (this) {
4777                synchronized (mPidsSelfLocked) {
4778                    proc = mPidsSelfLocked.get(pids[i]);
4779                    oomAdj = proc != null ? proc.setAdj : 0;
4780                }
4781            }
4782            long[] tmpUss = new long[1];
4783            pss[i] = Debug.getPss(pids[i], tmpUss);
4784            if (proc != null) {
4785                synchronized (this) {
4786                    if (proc.thread != null && proc.setAdj == oomAdj) {
4787                        // Record this for posterity if the process has been stable.
4788                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4789                    }
4790                }
4791            }
4792        }
4793        return pss;
4794    }
4795
4796    @Override
4797    public void killApplicationProcess(String processName, int uid) {
4798        if (processName == null) {
4799            return;
4800        }
4801
4802        int callerUid = Binder.getCallingUid();
4803        // Only the system server can kill an application
4804        if (callerUid == Process.SYSTEM_UID) {
4805            synchronized (this) {
4806                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4807                if (app != null && app.thread != null) {
4808                    try {
4809                        app.thread.scheduleSuicide();
4810                    } catch (RemoteException e) {
4811                        // If the other end already died, then our work here is done.
4812                    }
4813                } else {
4814                    Slog.w(TAG, "Process/uid not found attempting kill of "
4815                            + processName + " / " + uid);
4816                }
4817            }
4818        } else {
4819            throw new SecurityException(callerUid + " cannot kill app process: " +
4820                    processName);
4821        }
4822    }
4823
4824    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4825        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4826                false, true, false, false, UserHandle.getUserId(uid), reason);
4827        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4828                Uri.fromParts("package", packageName, null));
4829        if (!mProcessesReady) {
4830            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4831                    | Intent.FLAG_RECEIVER_FOREGROUND);
4832        }
4833        intent.putExtra(Intent.EXTRA_UID, uid);
4834        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4835        broadcastIntentLocked(null, null, intent,
4836                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4837                false, false,
4838                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4839    }
4840
4841    private void forceStopUserLocked(int userId, String reason) {
4842        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4843        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4844        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4845                | Intent.FLAG_RECEIVER_FOREGROUND);
4846        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4847        broadcastIntentLocked(null, null, intent,
4848                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4849                false, false,
4850                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4851    }
4852
4853    private final boolean killPackageProcessesLocked(String packageName, int appId,
4854            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4855            boolean doit, boolean evenPersistent, String reason) {
4856        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4857
4858        // Remove all processes this package may have touched: all with the
4859        // same UID (except for the system or root user), and all whose name
4860        // matches the package name.
4861        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4862        final int NP = mProcessNames.getMap().size();
4863        for (int ip=0; ip<NP; ip++) {
4864            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4865            final int NA = apps.size();
4866            for (int ia=0; ia<NA; ia++) {
4867                ProcessRecord app = apps.valueAt(ia);
4868                if (app.persistent && !evenPersistent) {
4869                    // we don't kill persistent processes
4870                    continue;
4871                }
4872                if (app.removed) {
4873                    if (doit) {
4874                        procs.add(app);
4875                    }
4876                    continue;
4877                }
4878
4879                // Skip process if it doesn't meet our oom adj requirement.
4880                if (app.setAdj < minOomAdj) {
4881                    continue;
4882                }
4883
4884                // If no package is specified, we call all processes under the
4885                // give user id.
4886                if (packageName == null) {
4887                    if (app.userId != userId) {
4888                        continue;
4889                    }
4890                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4891                        continue;
4892                    }
4893                // Package has been specified, we want to hit all processes
4894                // that match it.  We need to qualify this by the processes
4895                // that are running under the specified app and user ID.
4896                } else {
4897                    if (UserHandle.getAppId(app.uid) != appId) {
4898                        continue;
4899                    }
4900                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4901                        continue;
4902                    }
4903                    if (!app.pkgList.containsKey(packageName)) {
4904                        continue;
4905                    }
4906                }
4907
4908                // Process has passed all conditions, kill it!
4909                if (!doit) {
4910                    return true;
4911                }
4912                app.removed = true;
4913                procs.add(app);
4914            }
4915        }
4916
4917        int N = procs.size();
4918        for (int i=0; i<N; i++) {
4919            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4920        }
4921        updateOomAdjLocked();
4922        return N > 0;
4923    }
4924
4925    private final boolean forceStopPackageLocked(String name, int appId,
4926            boolean callerWillRestart, boolean purgeCache, boolean doit,
4927            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4928        int i;
4929        int N;
4930
4931        if (userId == UserHandle.USER_ALL && name == null) {
4932            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4933        }
4934
4935        if (appId < 0 && name != null) {
4936            try {
4937                appId = UserHandle.getAppId(
4938                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4939            } catch (RemoteException e) {
4940            }
4941        }
4942
4943        if (doit) {
4944            if (name != null) {
4945                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4946                        + " user=" + userId + ": " + reason);
4947            } else {
4948                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4949            }
4950
4951            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4952            for (int ip=pmap.size()-1; ip>=0; ip--) {
4953                SparseArray<Long> ba = pmap.valueAt(ip);
4954                for (i=ba.size()-1; i>=0; i--) {
4955                    boolean remove = false;
4956                    final int entUid = ba.keyAt(i);
4957                    if (name != null) {
4958                        if (userId == UserHandle.USER_ALL) {
4959                            if (UserHandle.getAppId(entUid) == appId) {
4960                                remove = true;
4961                            }
4962                        } else {
4963                            if (entUid == UserHandle.getUid(userId, appId)) {
4964                                remove = true;
4965                            }
4966                        }
4967                    } else if (UserHandle.getUserId(entUid) == userId) {
4968                        remove = true;
4969                    }
4970                    if (remove) {
4971                        ba.removeAt(i);
4972                    }
4973                }
4974                if (ba.size() == 0) {
4975                    pmap.removeAt(ip);
4976                }
4977            }
4978        }
4979
4980        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4981                -100, callerWillRestart, true, doit, evenPersistent,
4982                name == null ? ("stop user " + userId) : ("stop " + name));
4983
4984        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4985            if (!doit) {
4986                return true;
4987            }
4988            didSomething = true;
4989        }
4990
4991        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4992            if (!doit) {
4993                return true;
4994            }
4995            didSomething = true;
4996        }
4997
4998        if (name == null) {
4999            // Remove all sticky broadcasts from this user.
5000            mStickyBroadcasts.remove(userId);
5001        }
5002
5003        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5004        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5005                userId, providers)) {
5006            if (!doit) {
5007                return true;
5008            }
5009            didSomething = true;
5010        }
5011        N = providers.size();
5012        for (i=0; i<N; i++) {
5013            removeDyingProviderLocked(null, providers.get(i), true);
5014        }
5015
5016        // Remove transient permissions granted from/to this package/user
5017        removeUriPermissionsForPackageLocked(name, userId, false);
5018
5019        if (name == null || uninstalling) {
5020            // Remove pending intents.  For now we only do this when force
5021            // stopping users, because we have some problems when doing this
5022            // for packages -- app widgets are not currently cleaned up for
5023            // such packages, so they can be left with bad pending intents.
5024            if (mIntentSenderRecords.size() > 0) {
5025                Iterator<WeakReference<PendingIntentRecord>> it
5026                        = mIntentSenderRecords.values().iterator();
5027                while (it.hasNext()) {
5028                    WeakReference<PendingIntentRecord> wpir = it.next();
5029                    if (wpir == null) {
5030                        it.remove();
5031                        continue;
5032                    }
5033                    PendingIntentRecord pir = wpir.get();
5034                    if (pir == null) {
5035                        it.remove();
5036                        continue;
5037                    }
5038                    if (name == null) {
5039                        // Stopping user, remove all objects for the user.
5040                        if (pir.key.userId != userId) {
5041                            // Not the same user, skip it.
5042                            continue;
5043                        }
5044                    } else {
5045                        if (UserHandle.getAppId(pir.uid) != appId) {
5046                            // Different app id, skip it.
5047                            continue;
5048                        }
5049                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5050                            // Different user, skip it.
5051                            continue;
5052                        }
5053                        if (!pir.key.packageName.equals(name)) {
5054                            // Different package, skip it.
5055                            continue;
5056                        }
5057                    }
5058                    if (!doit) {
5059                        return true;
5060                    }
5061                    didSomething = true;
5062                    it.remove();
5063                    pir.canceled = true;
5064                    if (pir.key.activity != null) {
5065                        pir.key.activity.pendingResults.remove(pir.ref);
5066                    }
5067                }
5068            }
5069        }
5070
5071        if (doit) {
5072            if (purgeCache && name != null) {
5073                AttributeCache ac = AttributeCache.instance();
5074                if (ac != null) {
5075                    ac.removePackage(name);
5076                }
5077            }
5078            if (mBooted) {
5079                mStackSupervisor.resumeTopActivitiesLocked();
5080                mStackSupervisor.scheduleIdleLocked();
5081            }
5082        }
5083
5084        return didSomething;
5085    }
5086
5087    private final boolean removeProcessLocked(ProcessRecord app,
5088            boolean callerWillRestart, boolean allowRestart, String reason) {
5089        final String name = app.processName;
5090        final int uid = app.uid;
5091        if (DEBUG_PROCESSES) Slog.d(
5092            TAG, "Force removing proc " + app.toShortString() + " (" + name
5093            + "/" + uid + ")");
5094
5095        mProcessNames.remove(name, uid);
5096        mIsolatedProcesses.remove(app.uid);
5097        if (mHeavyWeightProcess == app) {
5098            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5099                    mHeavyWeightProcess.userId, 0));
5100            mHeavyWeightProcess = null;
5101        }
5102        boolean needRestart = false;
5103        if (app.pid > 0 && app.pid != MY_PID) {
5104            int pid = app.pid;
5105            synchronized (mPidsSelfLocked) {
5106                mPidsSelfLocked.remove(pid);
5107                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5108            }
5109            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5110                    app.processName, app.info.uid);
5111            if (app.isolated) {
5112                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5113            }
5114            killUnneededProcessLocked(app, reason);
5115            handleAppDiedLocked(app, true, allowRestart);
5116            removeLruProcessLocked(app);
5117
5118            if (app.persistent && !app.isolated) {
5119                if (!callerWillRestart) {
5120                    addAppLocked(app.info, false, null /* ABI override */);
5121                } else {
5122                    needRestart = true;
5123                }
5124            }
5125        } else {
5126            mRemovedProcesses.add(app);
5127        }
5128
5129        return needRestart;
5130    }
5131
5132    private final void processStartTimedOutLocked(ProcessRecord app) {
5133        final int pid = app.pid;
5134        boolean gone = false;
5135        synchronized (mPidsSelfLocked) {
5136            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5137            if (knownApp != null && knownApp.thread == null) {
5138                mPidsSelfLocked.remove(pid);
5139                gone = true;
5140            }
5141        }
5142
5143        if (gone) {
5144            Slog.w(TAG, "Process " + app + " failed to attach");
5145            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5146                    pid, app.uid, app.processName);
5147            mProcessNames.remove(app.processName, app.uid);
5148            mIsolatedProcesses.remove(app.uid);
5149            if (mHeavyWeightProcess == app) {
5150                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5151                        mHeavyWeightProcess.userId, 0));
5152                mHeavyWeightProcess = null;
5153            }
5154            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5155                    app.processName, app.info.uid);
5156            if (app.isolated) {
5157                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5158            }
5159            // Take care of any launching providers waiting for this process.
5160            checkAppInLaunchingProvidersLocked(app, true);
5161            // Take care of any services that are waiting for the process.
5162            mServices.processStartTimedOutLocked(app);
5163            killUnneededProcessLocked(app, "start timeout");
5164            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5165                Slog.w(TAG, "Unattached app died before backup, skipping");
5166                try {
5167                    IBackupManager bm = IBackupManager.Stub.asInterface(
5168                            ServiceManager.getService(Context.BACKUP_SERVICE));
5169                    bm.agentDisconnected(app.info.packageName);
5170                } catch (RemoteException e) {
5171                    // Can't happen; the backup manager is local
5172                }
5173            }
5174            if (isPendingBroadcastProcessLocked(pid)) {
5175                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5176                skipPendingBroadcastLocked(pid);
5177            }
5178        } else {
5179            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5180        }
5181    }
5182
5183    private final boolean attachApplicationLocked(IApplicationThread thread,
5184            int pid) {
5185
5186        // Find the application record that is being attached...  either via
5187        // the pid if we are running in multiple processes, or just pull the
5188        // next app record if we are emulating process with anonymous threads.
5189        ProcessRecord app;
5190        if (pid != MY_PID && pid >= 0) {
5191            synchronized (mPidsSelfLocked) {
5192                app = mPidsSelfLocked.get(pid);
5193            }
5194        } else {
5195            app = null;
5196        }
5197
5198        if (app == null) {
5199            Slog.w(TAG, "No pending application record for pid " + pid
5200                    + " (IApplicationThread " + thread + "); dropping process");
5201            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5202            if (pid > 0 && pid != MY_PID) {
5203                Process.killProcessQuiet(pid);
5204            } else {
5205                try {
5206                    thread.scheduleExit();
5207                } catch (Exception e) {
5208                    // Ignore exceptions.
5209                }
5210            }
5211            return false;
5212        }
5213
5214        // If this application record is still attached to a previous
5215        // process, clean it up now.
5216        if (app.thread != null) {
5217            handleAppDiedLocked(app, true, true);
5218        }
5219
5220        // Tell the process all about itself.
5221
5222        if (localLOGV) Slog.v(
5223                TAG, "Binding process pid " + pid + " to record " + app);
5224
5225        final String processName = app.processName;
5226        try {
5227            AppDeathRecipient adr = new AppDeathRecipient(
5228                    app, pid, thread);
5229            thread.asBinder().linkToDeath(adr, 0);
5230            app.deathRecipient = adr;
5231        } catch (RemoteException e) {
5232            app.resetPackageList(mProcessStats);
5233            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5234            return false;
5235        }
5236
5237        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5238
5239        app.makeActive(thread, mProcessStats);
5240        app.curAdj = app.setAdj = -100;
5241        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5242        app.forcingToForeground = null;
5243        updateProcessForegroundLocked(app, false, false);
5244        app.hasShownUi = false;
5245        app.debugging = false;
5246        app.cached = false;
5247
5248        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5249
5250        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5251        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5252
5253        if (!normalMode) {
5254            Slog.i(TAG, "Launching preboot mode app: " + app);
5255        }
5256
5257        if (localLOGV) Slog.v(
5258            TAG, "New app record " + app
5259            + " thread=" + thread.asBinder() + " pid=" + pid);
5260        try {
5261            int testMode = IApplicationThread.DEBUG_OFF;
5262            if (mDebugApp != null && mDebugApp.equals(processName)) {
5263                testMode = mWaitForDebugger
5264                    ? IApplicationThread.DEBUG_WAIT
5265                    : IApplicationThread.DEBUG_ON;
5266                app.debugging = true;
5267                if (mDebugTransient) {
5268                    mDebugApp = mOrigDebugApp;
5269                    mWaitForDebugger = mOrigWaitForDebugger;
5270                }
5271            }
5272            String profileFile = app.instrumentationProfileFile;
5273            ParcelFileDescriptor profileFd = null;
5274            boolean profileAutoStop = false;
5275            if (mProfileApp != null && mProfileApp.equals(processName)) {
5276                mProfileProc = app;
5277                profileFile = mProfileFile;
5278                profileFd = mProfileFd;
5279                profileAutoStop = mAutoStopProfiler;
5280            }
5281            boolean enableOpenGlTrace = false;
5282            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5283                enableOpenGlTrace = true;
5284                mOpenGlTraceApp = null;
5285            }
5286
5287            // If the app is being launched for restore or full backup, set it up specially
5288            boolean isRestrictedBackupMode = false;
5289            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5290                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5291                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5292                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5293            }
5294
5295            ensurePackageDexOpt(app.instrumentationInfo != null
5296                    ? app.instrumentationInfo.packageName
5297                    : app.info.packageName);
5298            if (app.instrumentationClass != null) {
5299                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5300            }
5301            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5302                    + processName + " with config " + mConfiguration);
5303            ApplicationInfo appInfo = app.instrumentationInfo != null
5304                    ? app.instrumentationInfo : app.info;
5305            app.compat = compatibilityInfoForPackageLocked(appInfo);
5306            if (profileFd != null) {
5307                profileFd = profileFd.dup();
5308            }
5309            thread.bindApplication(processName, appInfo, providers,
5310                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5311                    app.instrumentationArguments, app.instrumentationWatcher,
5312                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5313                    isRestrictedBackupMode || !normalMode, app.persistent,
5314                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5315                    mCoreSettingsObserver.getCoreSettingsLocked());
5316            updateLruProcessLocked(app, false, null);
5317            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5318        } catch (Exception e) {
5319            // todo: Yikes!  What should we do?  For now we will try to
5320            // start another process, but that could easily get us in
5321            // an infinite loop of restarting processes...
5322            Slog.w(TAG, "Exception thrown during bind!", e);
5323
5324            app.resetPackageList(mProcessStats);
5325            app.unlinkDeathRecipient();
5326            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5327            return false;
5328        }
5329
5330        // Remove this record from the list of starting applications.
5331        mPersistentStartingProcesses.remove(app);
5332        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5333                "Attach application locked removing on hold: " + app);
5334        mProcessesOnHold.remove(app);
5335
5336        boolean badApp = false;
5337        boolean didSomething = false;
5338
5339        // See if the top visible activity is waiting to run in this process...
5340        if (normalMode) {
5341            try {
5342                if (mStackSupervisor.attachApplicationLocked(app)) {
5343                    didSomething = true;
5344                }
5345            } catch (Exception e) {
5346                badApp = true;
5347            }
5348        }
5349
5350        // Find any services that should be running in this process...
5351        if (!badApp) {
5352            try {
5353                didSomething |= mServices.attachApplicationLocked(app, processName);
5354            } catch (Exception e) {
5355                badApp = true;
5356            }
5357        }
5358
5359        // Check if a next-broadcast receiver is in this process...
5360        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5361            try {
5362                didSomething |= sendPendingBroadcastsLocked(app);
5363            } catch (Exception e) {
5364                // If the app died trying to launch the receiver we declare it 'bad'
5365                badApp = true;
5366            }
5367        }
5368
5369        // Check whether the next backup agent is in this process...
5370        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5371            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5372            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5373            try {
5374                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5375                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5376                        mBackupTarget.backupMode);
5377            } catch (Exception e) {
5378                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5379                e.printStackTrace();
5380            }
5381        }
5382
5383        if (badApp) {
5384            // todo: Also need to kill application to deal with all
5385            // kinds of exceptions.
5386            handleAppDiedLocked(app, false, true);
5387            return false;
5388        }
5389
5390        if (!didSomething) {
5391            updateOomAdjLocked();
5392        }
5393
5394        return true;
5395    }
5396
5397    @Override
5398    public final void attachApplication(IApplicationThread thread) {
5399        synchronized (this) {
5400            int callingPid = Binder.getCallingPid();
5401            final long origId = Binder.clearCallingIdentity();
5402            attachApplicationLocked(thread, callingPid);
5403            Binder.restoreCallingIdentity(origId);
5404        }
5405    }
5406
5407    @Override
5408    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5409        final long origId = Binder.clearCallingIdentity();
5410        synchronized (this) {
5411            ActivityStack stack = ActivityRecord.getStackLocked(token);
5412            if (stack != null) {
5413                ActivityRecord r =
5414                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5415                if (stopProfiling) {
5416                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5417                        try {
5418                            mProfileFd.close();
5419                        } catch (IOException e) {
5420                        }
5421                        clearProfilerLocked();
5422                    }
5423                }
5424            }
5425        }
5426        Binder.restoreCallingIdentity(origId);
5427    }
5428
5429    void enableScreenAfterBoot() {
5430        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5431                SystemClock.uptimeMillis());
5432        mWindowManager.enableScreenAfterBoot();
5433
5434        synchronized (this) {
5435            updateEventDispatchingLocked();
5436        }
5437    }
5438
5439    @Override
5440    public void showBootMessage(final CharSequence msg, final boolean always) {
5441        enforceNotIsolatedCaller("showBootMessage");
5442        mWindowManager.showBootMessage(msg, always);
5443    }
5444
5445    @Override
5446    public void dismissKeyguardOnNextActivity() {
5447        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5448        final long token = Binder.clearCallingIdentity();
5449        try {
5450            synchronized (this) {
5451                if (DEBUG_LOCKSCREEN) logLockScreen("");
5452                if (mLockScreenShown) {
5453                    mLockScreenShown = false;
5454                    comeOutOfSleepIfNeededLocked();
5455                }
5456                mStackSupervisor.setDismissKeyguard(true);
5457            }
5458        } finally {
5459            Binder.restoreCallingIdentity(token);
5460        }
5461    }
5462
5463    final void finishBooting() {
5464        // Register receivers to handle package update events
5465        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5466
5467        synchronized (this) {
5468            // Ensure that any processes we had put on hold are now started
5469            // up.
5470            final int NP = mProcessesOnHold.size();
5471            if (NP > 0) {
5472                ArrayList<ProcessRecord> procs =
5473                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5474                for (int ip=0; ip<NP; ip++) {
5475                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5476                            + procs.get(ip));
5477                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5478                }
5479            }
5480
5481            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5482                // Start looking for apps that are abusing wake locks.
5483                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5484                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5485                // Tell anyone interested that we are done booting!
5486                SystemProperties.set("sys.boot_completed", "1");
5487                SystemProperties.set("dev.bootcomplete", "1");
5488                for (int i=0; i<mStartedUsers.size(); i++) {
5489                    UserStartedState uss = mStartedUsers.valueAt(i);
5490                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5491                        uss.mState = UserStartedState.STATE_RUNNING;
5492                        final int userId = mStartedUsers.keyAt(i);
5493                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5494                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5495                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5496                        broadcastIntentLocked(null, null, intent, null,
5497                                new IIntentReceiver.Stub() {
5498                                    @Override
5499                                    public void performReceive(Intent intent, int resultCode,
5500                                            String data, Bundle extras, boolean ordered,
5501                                            boolean sticky, int sendingUser) {
5502                                        synchronized (ActivityManagerService.this) {
5503                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5504                                                    true, false);
5505                                        }
5506                                    }
5507                                },
5508                                0, null, null,
5509                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5510                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5511                                userId);
5512                    }
5513                }
5514                scheduleStartProfilesLocked();
5515            }
5516        }
5517    }
5518
5519    final void ensureBootCompleted() {
5520        boolean booting;
5521        boolean enableScreen;
5522        synchronized (this) {
5523            booting = mBooting;
5524            mBooting = false;
5525            enableScreen = !mBooted;
5526            mBooted = true;
5527        }
5528
5529        if (booting) {
5530            finishBooting();
5531        }
5532
5533        if (enableScreen) {
5534            enableScreenAfterBoot();
5535        }
5536    }
5537
5538    @Override
5539    public final void activityResumed(IBinder token) {
5540        final long origId = Binder.clearCallingIdentity();
5541        synchronized(this) {
5542            ActivityStack stack = ActivityRecord.getStackLocked(token);
5543            if (stack != null) {
5544                ActivityRecord.activityResumedLocked(token);
5545            }
5546        }
5547        Binder.restoreCallingIdentity(origId);
5548    }
5549
5550    @Override
5551    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5552        final long origId = Binder.clearCallingIdentity();
5553        synchronized(this) {
5554            ActivityStack stack = ActivityRecord.getStackLocked(token);
5555            if (stack != null) {
5556                stack.activityPausedLocked(token, false, persistentState);
5557            }
5558        }
5559        Binder.restoreCallingIdentity(origId);
5560    }
5561
5562    @Override
5563    public final void activityStopped(IBinder token, Bundle icicle,
5564            PersistableBundle persistentState, CharSequence description) {
5565        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5566
5567        // Refuse possible leaked file descriptors
5568        if (icicle != null && icicle.hasFileDescriptors()) {
5569            throw new IllegalArgumentException("File descriptors passed in Bundle");
5570        }
5571
5572        final long origId = Binder.clearCallingIdentity();
5573
5574        synchronized (this) {
5575            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5576            if (r != null) {
5577                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5578            }
5579        }
5580
5581        trimApplications();
5582
5583        Binder.restoreCallingIdentity(origId);
5584    }
5585
5586    @Override
5587    public final void activityDestroyed(IBinder token) {
5588        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5589        synchronized (this) {
5590            ActivityStack stack = ActivityRecord.getStackLocked(token);
5591            if (stack != null) {
5592                stack.activityDestroyedLocked(token);
5593            }
5594        }
5595    }
5596
5597    @Override
5598    public String getCallingPackage(IBinder token) {
5599        synchronized (this) {
5600            ActivityRecord r = getCallingRecordLocked(token);
5601            return r != null ? r.info.packageName : null;
5602        }
5603    }
5604
5605    @Override
5606    public ComponentName getCallingActivity(IBinder token) {
5607        synchronized (this) {
5608            ActivityRecord r = getCallingRecordLocked(token);
5609            return r != null ? r.intent.getComponent() : null;
5610        }
5611    }
5612
5613    private ActivityRecord getCallingRecordLocked(IBinder token) {
5614        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5615        if (r == null) {
5616            return null;
5617        }
5618        return r.resultTo;
5619    }
5620
5621    @Override
5622    public ComponentName getActivityClassForToken(IBinder token) {
5623        synchronized(this) {
5624            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5625            if (r == null) {
5626                return null;
5627            }
5628            return r.intent.getComponent();
5629        }
5630    }
5631
5632    @Override
5633    public String getPackageForToken(IBinder token) {
5634        synchronized(this) {
5635            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5636            if (r == null) {
5637                return null;
5638            }
5639            return r.packageName;
5640        }
5641    }
5642
5643    @Override
5644    public IIntentSender getIntentSender(int type,
5645            String packageName, IBinder token, String resultWho,
5646            int requestCode, Intent[] intents, String[] resolvedTypes,
5647            int flags, Bundle options, int userId) {
5648        enforceNotIsolatedCaller("getIntentSender");
5649        // Refuse possible leaked file descriptors
5650        if (intents != null) {
5651            if (intents.length < 1) {
5652                throw new IllegalArgumentException("Intents array length must be >= 1");
5653            }
5654            for (int i=0; i<intents.length; i++) {
5655                Intent intent = intents[i];
5656                if (intent != null) {
5657                    if (intent.hasFileDescriptors()) {
5658                        throw new IllegalArgumentException("File descriptors passed in Intent");
5659                    }
5660                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5661                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5662                        throw new IllegalArgumentException(
5663                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5664                    }
5665                    intents[i] = new Intent(intent);
5666                }
5667            }
5668            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5669                throw new IllegalArgumentException(
5670                        "Intent array length does not match resolvedTypes length");
5671            }
5672        }
5673        if (options != null) {
5674            if (options.hasFileDescriptors()) {
5675                throw new IllegalArgumentException("File descriptors passed in options");
5676            }
5677        }
5678
5679        synchronized(this) {
5680            int callingUid = Binder.getCallingUid();
5681            int origUserId = userId;
5682            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5683                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5684                    "getIntentSender", null);
5685            if (origUserId == UserHandle.USER_CURRENT) {
5686                // We don't want to evaluate this until the pending intent is
5687                // actually executed.  However, we do want to always do the
5688                // security checking for it above.
5689                userId = UserHandle.USER_CURRENT;
5690            }
5691            try {
5692                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5693                    int uid = AppGlobals.getPackageManager()
5694                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5695                    if (!UserHandle.isSameApp(callingUid, uid)) {
5696                        String msg = "Permission Denial: getIntentSender() from pid="
5697                            + Binder.getCallingPid()
5698                            + ", uid=" + Binder.getCallingUid()
5699                            + ", (need uid=" + uid + ")"
5700                            + " is not allowed to send as package " + packageName;
5701                        Slog.w(TAG, msg);
5702                        throw new SecurityException(msg);
5703                    }
5704                }
5705
5706                return getIntentSenderLocked(type, packageName, callingUid, userId,
5707                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5708
5709            } catch (RemoteException e) {
5710                throw new SecurityException(e);
5711            }
5712        }
5713    }
5714
5715    IIntentSender getIntentSenderLocked(int type, String packageName,
5716            int callingUid, int userId, IBinder token, String resultWho,
5717            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5718            Bundle options) {
5719        if (DEBUG_MU)
5720            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5721        ActivityRecord activity = null;
5722        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5723            activity = ActivityRecord.isInStackLocked(token);
5724            if (activity == null) {
5725                return null;
5726            }
5727            if (activity.finishing) {
5728                return null;
5729            }
5730        }
5731
5732        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5733        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5734        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5735        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5736                |PendingIntent.FLAG_UPDATE_CURRENT);
5737
5738        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5739                type, packageName, activity, resultWho,
5740                requestCode, intents, resolvedTypes, flags, options, userId);
5741        WeakReference<PendingIntentRecord> ref;
5742        ref = mIntentSenderRecords.get(key);
5743        PendingIntentRecord rec = ref != null ? ref.get() : null;
5744        if (rec != null) {
5745            if (!cancelCurrent) {
5746                if (updateCurrent) {
5747                    if (rec.key.requestIntent != null) {
5748                        rec.key.requestIntent.replaceExtras(intents != null ?
5749                                intents[intents.length - 1] : null);
5750                    }
5751                    if (intents != null) {
5752                        intents[intents.length-1] = rec.key.requestIntent;
5753                        rec.key.allIntents = intents;
5754                        rec.key.allResolvedTypes = resolvedTypes;
5755                    } else {
5756                        rec.key.allIntents = null;
5757                        rec.key.allResolvedTypes = null;
5758                    }
5759                }
5760                return rec;
5761            }
5762            rec.canceled = true;
5763            mIntentSenderRecords.remove(key);
5764        }
5765        if (noCreate) {
5766            return rec;
5767        }
5768        rec = new PendingIntentRecord(this, key, callingUid);
5769        mIntentSenderRecords.put(key, rec.ref);
5770        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5771            if (activity.pendingResults == null) {
5772                activity.pendingResults
5773                        = new HashSet<WeakReference<PendingIntentRecord>>();
5774            }
5775            activity.pendingResults.add(rec.ref);
5776        }
5777        return rec;
5778    }
5779
5780    @Override
5781    public void cancelIntentSender(IIntentSender sender) {
5782        if (!(sender instanceof PendingIntentRecord)) {
5783            return;
5784        }
5785        synchronized(this) {
5786            PendingIntentRecord rec = (PendingIntentRecord)sender;
5787            try {
5788                int uid = AppGlobals.getPackageManager()
5789                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5790                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5791                    String msg = "Permission Denial: cancelIntentSender() from pid="
5792                        + Binder.getCallingPid()
5793                        + ", uid=" + Binder.getCallingUid()
5794                        + " is not allowed to cancel packges "
5795                        + rec.key.packageName;
5796                    Slog.w(TAG, msg);
5797                    throw new SecurityException(msg);
5798                }
5799            } catch (RemoteException e) {
5800                throw new SecurityException(e);
5801            }
5802            cancelIntentSenderLocked(rec, true);
5803        }
5804    }
5805
5806    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5807        rec.canceled = true;
5808        mIntentSenderRecords.remove(rec.key);
5809        if (cleanActivity && rec.key.activity != null) {
5810            rec.key.activity.pendingResults.remove(rec.ref);
5811        }
5812    }
5813
5814    @Override
5815    public String getPackageForIntentSender(IIntentSender pendingResult) {
5816        if (!(pendingResult instanceof PendingIntentRecord)) {
5817            return null;
5818        }
5819        try {
5820            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5821            return res.key.packageName;
5822        } catch (ClassCastException e) {
5823        }
5824        return null;
5825    }
5826
5827    @Override
5828    public int getUidForIntentSender(IIntentSender sender) {
5829        if (sender instanceof PendingIntentRecord) {
5830            try {
5831                PendingIntentRecord res = (PendingIntentRecord)sender;
5832                return res.uid;
5833            } catch (ClassCastException e) {
5834            }
5835        }
5836        return -1;
5837    }
5838
5839    @Override
5840    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5841        if (!(pendingResult instanceof PendingIntentRecord)) {
5842            return false;
5843        }
5844        try {
5845            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5846            if (res.key.allIntents == null) {
5847                return false;
5848            }
5849            for (int i=0; i<res.key.allIntents.length; i++) {
5850                Intent intent = res.key.allIntents[i];
5851                if (intent.getPackage() != null && intent.getComponent() != null) {
5852                    return false;
5853                }
5854            }
5855            return true;
5856        } catch (ClassCastException e) {
5857        }
5858        return false;
5859    }
5860
5861    @Override
5862    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5863        if (!(pendingResult instanceof PendingIntentRecord)) {
5864            return false;
5865        }
5866        try {
5867            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5868            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5869                return true;
5870            }
5871            return false;
5872        } catch (ClassCastException e) {
5873        }
5874        return false;
5875    }
5876
5877    @Override
5878    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5879        if (!(pendingResult instanceof PendingIntentRecord)) {
5880            return null;
5881        }
5882        try {
5883            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5884            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5885        } catch (ClassCastException e) {
5886        }
5887        return null;
5888    }
5889
5890    @Override
5891    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5892        if (!(pendingResult instanceof PendingIntentRecord)) {
5893            return null;
5894        }
5895        try {
5896            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5897            Intent intent = res.key.requestIntent;
5898            if (intent != null) {
5899                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5900                        || res.lastTagPrefix.equals(prefix))) {
5901                    return res.lastTag;
5902                }
5903                res.lastTagPrefix = prefix;
5904                StringBuilder sb = new StringBuilder(128);
5905                if (prefix != null) {
5906                    sb.append(prefix);
5907                }
5908                if (intent.getAction() != null) {
5909                    sb.append(intent.getAction());
5910                } else if (intent.getComponent() != null) {
5911                    intent.getComponent().appendShortString(sb);
5912                } else {
5913                    sb.append("?");
5914                }
5915                return res.lastTag = sb.toString();
5916            }
5917        } catch (ClassCastException e) {
5918        }
5919        return null;
5920    }
5921
5922    @Override
5923    public void setProcessLimit(int max) {
5924        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5925                "setProcessLimit()");
5926        synchronized (this) {
5927            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5928            mProcessLimitOverride = max;
5929        }
5930        trimApplications();
5931    }
5932
5933    @Override
5934    public int getProcessLimit() {
5935        synchronized (this) {
5936            return mProcessLimitOverride;
5937        }
5938    }
5939
5940    void foregroundTokenDied(ForegroundToken token) {
5941        synchronized (ActivityManagerService.this) {
5942            synchronized (mPidsSelfLocked) {
5943                ForegroundToken cur
5944                    = mForegroundProcesses.get(token.pid);
5945                if (cur != token) {
5946                    return;
5947                }
5948                mForegroundProcesses.remove(token.pid);
5949                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5950                if (pr == null) {
5951                    return;
5952                }
5953                pr.forcingToForeground = null;
5954                updateProcessForegroundLocked(pr, false, false);
5955            }
5956            updateOomAdjLocked();
5957        }
5958    }
5959
5960    @Override
5961    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5962        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5963                "setProcessForeground()");
5964        synchronized(this) {
5965            boolean changed = false;
5966
5967            synchronized (mPidsSelfLocked) {
5968                ProcessRecord pr = mPidsSelfLocked.get(pid);
5969                if (pr == null && isForeground) {
5970                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5971                    return;
5972                }
5973                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5974                if (oldToken != null) {
5975                    oldToken.token.unlinkToDeath(oldToken, 0);
5976                    mForegroundProcesses.remove(pid);
5977                    if (pr != null) {
5978                        pr.forcingToForeground = null;
5979                    }
5980                    changed = true;
5981                }
5982                if (isForeground && token != null) {
5983                    ForegroundToken newToken = new ForegroundToken() {
5984                        @Override
5985                        public void binderDied() {
5986                            foregroundTokenDied(this);
5987                        }
5988                    };
5989                    newToken.pid = pid;
5990                    newToken.token = token;
5991                    try {
5992                        token.linkToDeath(newToken, 0);
5993                        mForegroundProcesses.put(pid, newToken);
5994                        pr.forcingToForeground = token;
5995                        changed = true;
5996                    } catch (RemoteException e) {
5997                        // If the process died while doing this, we will later
5998                        // do the cleanup with the process death link.
5999                    }
6000                }
6001            }
6002
6003            if (changed) {
6004                updateOomAdjLocked();
6005            }
6006        }
6007    }
6008
6009    // =========================================================
6010    // PERMISSIONS
6011    // =========================================================
6012
6013    static class PermissionController extends IPermissionController.Stub {
6014        ActivityManagerService mActivityManagerService;
6015        PermissionController(ActivityManagerService activityManagerService) {
6016            mActivityManagerService = activityManagerService;
6017        }
6018
6019        @Override
6020        public boolean checkPermission(String permission, int pid, int uid) {
6021            return mActivityManagerService.checkPermission(permission, pid,
6022                    uid) == PackageManager.PERMISSION_GRANTED;
6023        }
6024    }
6025
6026    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6027        @Override
6028        public int checkComponentPermission(String permission, int pid, int uid,
6029                int owningUid, boolean exported) {
6030            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6031                    owningUid, exported);
6032        }
6033
6034        @Override
6035        public Object getAMSLock() {
6036            return ActivityManagerService.this;
6037        }
6038    }
6039
6040    /**
6041     * This can be called with or without the global lock held.
6042     */
6043    int checkComponentPermission(String permission, int pid, int uid,
6044            int owningUid, boolean exported) {
6045        // We might be performing an operation on behalf of an indirect binder
6046        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6047        // client identity accordingly before proceeding.
6048        Identity tlsIdentity = sCallerIdentity.get();
6049        if (tlsIdentity != null) {
6050            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6051                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6052            uid = tlsIdentity.uid;
6053            pid = tlsIdentity.pid;
6054        }
6055
6056        if (pid == MY_PID) {
6057            return PackageManager.PERMISSION_GRANTED;
6058        }
6059
6060        return ActivityManager.checkComponentPermission(permission, uid,
6061                owningUid, exported);
6062    }
6063
6064    /**
6065     * As the only public entry point for permissions checking, this method
6066     * can enforce the semantic that requesting a check on a null global
6067     * permission is automatically denied.  (Internally a null permission
6068     * string is used when calling {@link #checkComponentPermission} in cases
6069     * when only uid-based security is needed.)
6070     *
6071     * This can be called with or without the global lock held.
6072     */
6073    @Override
6074    public int checkPermission(String permission, int pid, int uid) {
6075        if (permission == null) {
6076            return PackageManager.PERMISSION_DENIED;
6077        }
6078        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6079    }
6080
6081    /**
6082     * Binder IPC calls go through the public entry point.
6083     * This can be called with or without the global lock held.
6084     */
6085    int checkCallingPermission(String permission) {
6086        return checkPermission(permission,
6087                Binder.getCallingPid(),
6088                UserHandle.getAppId(Binder.getCallingUid()));
6089    }
6090
6091    /**
6092     * This can be called with or without the global lock held.
6093     */
6094    void enforceCallingPermission(String permission, String func) {
6095        if (checkCallingPermission(permission)
6096                == PackageManager.PERMISSION_GRANTED) {
6097            return;
6098        }
6099
6100        String msg = "Permission Denial: " + func + " from pid="
6101                + Binder.getCallingPid()
6102                + ", uid=" + Binder.getCallingUid()
6103                + " requires " + permission;
6104        Slog.w(TAG, msg);
6105        throw new SecurityException(msg);
6106    }
6107
6108    /**
6109     * Determine if UID is holding permissions required to access {@link Uri} in
6110     * the given {@link ProviderInfo}. Final permission checking is always done
6111     * in {@link ContentProvider}.
6112     */
6113    private final boolean checkHoldingPermissionsLocked(
6114            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6115        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6116                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6117        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6118            return false;
6119        }
6120        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6121    }
6122
6123    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6124            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6125        if (pi.applicationInfo.uid == uid) {
6126            return true;
6127        } else if (!pi.exported) {
6128            return false;
6129        }
6130
6131        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6132        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6133        try {
6134            // check if target holds top-level <provider> permissions
6135            if (!readMet && pi.readPermission != null && considerUidPermissions
6136                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6137                readMet = true;
6138            }
6139            if (!writeMet && pi.writePermission != null && considerUidPermissions
6140                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6141                writeMet = true;
6142            }
6143
6144            // track if unprotected read/write is allowed; any denied
6145            // <path-permission> below removes this ability
6146            boolean allowDefaultRead = pi.readPermission == null;
6147            boolean allowDefaultWrite = pi.writePermission == null;
6148
6149            // check if target holds any <path-permission> that match uri
6150            final PathPermission[] pps = pi.pathPermissions;
6151            if (pps != null) {
6152                final String path = grantUri.uri.getPath();
6153                int i = pps.length;
6154                while (i > 0 && (!readMet || !writeMet)) {
6155                    i--;
6156                    PathPermission pp = pps[i];
6157                    if (pp.match(path)) {
6158                        if (!readMet) {
6159                            final String pprperm = pp.getReadPermission();
6160                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6161                                    + pprperm + " for " + pp.getPath()
6162                                    + ": match=" + pp.match(path)
6163                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6164                            if (pprperm != null) {
6165                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6166                                        == PERMISSION_GRANTED) {
6167                                    readMet = true;
6168                                } else {
6169                                    allowDefaultRead = false;
6170                                }
6171                            }
6172                        }
6173                        if (!writeMet) {
6174                            final String ppwperm = pp.getWritePermission();
6175                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6176                                    + ppwperm + " for " + pp.getPath()
6177                                    + ": match=" + pp.match(path)
6178                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6179                            if (ppwperm != null) {
6180                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6181                                        == PERMISSION_GRANTED) {
6182                                    writeMet = true;
6183                                } else {
6184                                    allowDefaultWrite = false;
6185                                }
6186                            }
6187                        }
6188                    }
6189                }
6190            }
6191
6192            // grant unprotected <provider> read/write, if not blocked by
6193            // <path-permission> above
6194            if (allowDefaultRead) readMet = true;
6195            if (allowDefaultWrite) writeMet = true;
6196
6197        } catch (RemoteException e) {
6198            return false;
6199        }
6200
6201        return readMet && writeMet;
6202    }
6203
6204    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6205        ProviderInfo pi = null;
6206        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6207        if (cpr != null) {
6208            pi = cpr.info;
6209        } else {
6210            try {
6211                pi = AppGlobals.getPackageManager().resolveContentProvider(
6212                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6213            } catch (RemoteException ex) {
6214            }
6215        }
6216        return pi;
6217    }
6218
6219    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6220        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6221        if (targetUris != null) {
6222            return targetUris.get(grantUri);
6223        }
6224        return null;
6225    }
6226
6227    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6228            String targetPkg, int targetUid, GrantUri grantUri) {
6229        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6230        if (targetUris == null) {
6231            targetUris = Maps.newArrayMap();
6232            mGrantedUriPermissions.put(targetUid, targetUris);
6233        }
6234
6235        UriPermission perm = targetUris.get(grantUri);
6236        if (perm == null) {
6237            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6238            targetUris.put(grantUri, perm);
6239        }
6240
6241        return perm;
6242    }
6243
6244    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6245            final int modeFlags) {
6246        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6247        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6248                : UriPermission.STRENGTH_OWNED;
6249
6250        // Root gets to do everything.
6251        if (uid == 0) {
6252            return true;
6253        }
6254
6255        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6256        if (perms == null) return false;
6257
6258        // First look for exact match
6259        final UriPermission exactPerm = perms.get(grantUri);
6260        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6261            return true;
6262        }
6263
6264        // No exact match, look for prefixes
6265        final int N = perms.size();
6266        for (int i = 0; i < N; i++) {
6267            final UriPermission perm = perms.valueAt(i);
6268            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6269                    && perm.getStrength(modeFlags) >= minStrength) {
6270                return true;
6271            }
6272        }
6273
6274        return false;
6275    }
6276
6277    @Override
6278    public int checkUriPermission(Uri uri, int pid, int uid,
6279            final int modeFlags, int userId) {
6280        enforceNotIsolatedCaller("checkUriPermission");
6281
6282        // Another redirected-binder-call permissions check as in
6283        // {@link checkComponentPermission}.
6284        Identity tlsIdentity = sCallerIdentity.get();
6285        if (tlsIdentity != null) {
6286            uid = tlsIdentity.uid;
6287            pid = tlsIdentity.pid;
6288        }
6289
6290        // Our own process gets to do everything.
6291        if (pid == MY_PID) {
6292            return PackageManager.PERMISSION_GRANTED;
6293        }
6294        synchronized (this) {
6295            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6296                    ? PackageManager.PERMISSION_GRANTED
6297                    : PackageManager.PERMISSION_DENIED;
6298        }
6299    }
6300
6301    /**
6302     * Check if the targetPkg can be granted permission to access uri by
6303     * the callingUid using the given modeFlags.  Throws a security exception
6304     * if callingUid is not allowed to do this.  Returns the uid of the target
6305     * if the URI permission grant should be performed; returns -1 if it is not
6306     * needed (for example targetPkg already has permission to access the URI).
6307     * If you already know the uid of the target, you can supply it in
6308     * lastTargetUid else set that to -1.
6309     */
6310    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6311            final int modeFlags, int lastTargetUid) {
6312        if (!Intent.isAccessUriMode(modeFlags)) {
6313            return -1;
6314        }
6315
6316        if (targetPkg != null) {
6317            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6318                    "Checking grant " + targetPkg + " permission to " + grantUri);
6319        }
6320
6321        final IPackageManager pm = AppGlobals.getPackageManager();
6322
6323        // If this is not a content: uri, we can't do anything with it.
6324        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6325            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6326                    "Can't grant URI permission for non-content URI: " + grantUri);
6327            return -1;
6328        }
6329
6330        final String authority = grantUri.uri.getAuthority();
6331        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6332        if (pi == null) {
6333            Slog.w(TAG, "No content provider found for permission check: " +
6334                    grantUri.uri.toSafeString());
6335            return -1;
6336        }
6337
6338        int targetUid = lastTargetUid;
6339        if (targetUid < 0 && targetPkg != null) {
6340            try {
6341                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6342                if (targetUid < 0) {
6343                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6344                            "Can't grant URI permission no uid for: " + targetPkg);
6345                    return -1;
6346                }
6347            } catch (RemoteException ex) {
6348                return -1;
6349            }
6350        }
6351
6352        if (targetUid >= 0) {
6353            // First...  does the target actually need this permission?
6354            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6355                // No need to grant the target this permission.
6356                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6357                        "Target " + targetPkg + " already has full permission to " + grantUri);
6358                return -1;
6359            }
6360        } else {
6361            // First...  there is no target package, so can anyone access it?
6362            boolean allowed = pi.exported;
6363            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6364                if (pi.readPermission != null) {
6365                    allowed = false;
6366                }
6367            }
6368            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6369                if (pi.writePermission != null) {
6370                    allowed = false;
6371                }
6372            }
6373            if (allowed) {
6374                return -1;
6375            }
6376        }
6377
6378        /* There is a special cross user grant if:
6379         * - The target is on another user.
6380         * - Apps on the current user can access the uri without any uid permissions.
6381         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6382         * grant uri permissions.
6383         */
6384        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6385                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6386                modeFlags, false /*without considering the uid permissions*/);
6387
6388        // Second...  is the provider allowing granting of URI permissions?
6389        if (!specialCrossUserGrant) {
6390            if (!pi.grantUriPermissions) {
6391                throw new SecurityException("Provider " + pi.packageName
6392                        + "/" + pi.name
6393                        + " does not allow granting of Uri permissions (uri "
6394                        + grantUri + ")");
6395            }
6396            if (pi.uriPermissionPatterns != null) {
6397                final int N = pi.uriPermissionPatterns.length;
6398                boolean allowed = false;
6399                for (int i=0; i<N; i++) {
6400                    if (pi.uriPermissionPatterns[i] != null
6401                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6402                        allowed = true;
6403                        break;
6404                    }
6405                }
6406                if (!allowed) {
6407                    throw new SecurityException("Provider " + pi.packageName
6408                            + "/" + pi.name
6409                            + " does not allow granting of permission to path of Uri "
6410                            + grantUri);
6411                }
6412            }
6413        }
6414
6415        // Third...  does the caller itself have permission to access
6416        // this uri?
6417        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6418            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6419                // Require they hold a strong enough Uri permission
6420                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6421                    throw new SecurityException("Uid " + callingUid
6422                            + " does not have permission to uri " + grantUri);
6423                }
6424            }
6425        }
6426        return targetUid;
6427    }
6428
6429    @Override
6430    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6431            final int modeFlags, int userId) {
6432        enforceNotIsolatedCaller("checkGrantUriPermission");
6433        synchronized(this) {
6434            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6435                    new GrantUri(userId, uri, false), modeFlags, -1);
6436        }
6437    }
6438
6439    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6440            final int modeFlags, UriPermissionOwner owner) {
6441        if (!Intent.isAccessUriMode(modeFlags)) {
6442            return;
6443        }
6444
6445        // So here we are: the caller has the assumed permission
6446        // to the uri, and the target doesn't.  Let's now give this to
6447        // the target.
6448
6449        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6450                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6451
6452        final String authority = grantUri.uri.getAuthority();
6453        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6454        if (pi == null) {
6455            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6456            return;
6457        }
6458
6459        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6460            grantUri.prefix = true;
6461        }
6462        final UriPermission perm = findOrCreateUriPermissionLocked(
6463                pi.packageName, targetPkg, targetUid, grantUri);
6464        perm.grantModes(modeFlags, owner);
6465    }
6466
6467    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6468            final int modeFlags, UriPermissionOwner owner) {
6469        if (targetPkg == null) {
6470            throw new NullPointerException("targetPkg");
6471        }
6472
6473        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6474                -1);
6475        if (targetUid < 0) {
6476            return;
6477        }
6478
6479        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6480                owner);
6481    }
6482
6483    static class NeededUriGrants extends ArrayList<GrantUri> {
6484        final String targetPkg;
6485        final int targetUid;
6486        final int flags;
6487
6488        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6489            this.targetPkg = targetPkg;
6490            this.targetUid = targetUid;
6491            this.flags = flags;
6492        }
6493    }
6494
6495    /**
6496     * Like checkGrantUriPermissionLocked, but takes an Intent.
6497     */
6498    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6499            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6500        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6501                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6502                + " clip=" + (intent != null ? intent.getClipData() : null)
6503                + " from " + intent + "; flags=0x"
6504                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6505
6506        if (targetPkg == null) {
6507            throw new NullPointerException("targetPkg");
6508        }
6509
6510        if (intent == null) {
6511            return null;
6512        }
6513        Uri data = intent.getData();
6514        ClipData clip = intent.getClipData();
6515        if (data == null && clip == null) {
6516            return null;
6517        }
6518        final IPackageManager pm = AppGlobals.getPackageManager();
6519        int targetUid;
6520        if (needed != null) {
6521            targetUid = needed.targetUid;
6522        } else {
6523            try {
6524                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6525            } catch (RemoteException ex) {
6526                return null;
6527            }
6528            if (targetUid < 0) {
6529                if (DEBUG_URI_PERMISSION) {
6530                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6531                            + " on user " + targetUserId);
6532                }
6533                return null;
6534            }
6535        }
6536        if (data != null) {
6537            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6538            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6539                    targetUid);
6540            if (targetUid > 0) {
6541                if (needed == null) {
6542                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6543                }
6544                needed.add(grantUri);
6545            }
6546        }
6547        if (clip != null) {
6548            for (int i=0; i<clip.getItemCount(); i++) {
6549                Uri uri = clip.getItemAt(i).getUri();
6550                if (uri != null) {
6551                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6552                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6553                            targetUid);
6554                    if (targetUid > 0) {
6555                        if (needed == null) {
6556                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6557                        }
6558                        needed.add(grantUri);
6559                    }
6560                } else {
6561                    Intent clipIntent = clip.getItemAt(i).getIntent();
6562                    if (clipIntent != null) {
6563                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6564                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6565                        if (newNeeded != null) {
6566                            needed = newNeeded;
6567                        }
6568                    }
6569                }
6570            }
6571        }
6572
6573        return needed;
6574    }
6575
6576    /**
6577     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6578     */
6579    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6580            UriPermissionOwner owner) {
6581        if (needed != null) {
6582            for (int i=0; i<needed.size(); i++) {
6583                GrantUri grantUri = needed.get(i);
6584                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6585                        grantUri, needed.flags, owner);
6586            }
6587        }
6588    }
6589
6590    void grantUriPermissionFromIntentLocked(int callingUid,
6591            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6592        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6593                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6594        if (needed == null) {
6595            return;
6596        }
6597
6598        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6599    }
6600
6601    @Override
6602    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6603            final int modeFlags, int userId) {
6604        enforceNotIsolatedCaller("grantUriPermission");
6605        GrantUri grantUri = new GrantUri(userId, uri, false);
6606        synchronized(this) {
6607            final ProcessRecord r = getRecordForAppLocked(caller);
6608            if (r == null) {
6609                throw new SecurityException("Unable to find app for caller "
6610                        + caller
6611                        + " when granting permission to uri " + grantUri);
6612            }
6613            if (targetPkg == null) {
6614                throw new IllegalArgumentException("null target");
6615            }
6616            if (grantUri == null) {
6617                throw new IllegalArgumentException("null uri");
6618            }
6619
6620            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6621                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6622                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6623                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6624
6625            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6626        }
6627    }
6628
6629    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6630        if (perm.modeFlags == 0) {
6631            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6632                    perm.targetUid);
6633            if (perms != null) {
6634                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6635                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6636
6637                perms.remove(perm.uri);
6638                if (perms.isEmpty()) {
6639                    mGrantedUriPermissions.remove(perm.targetUid);
6640                }
6641            }
6642        }
6643    }
6644
6645    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6646        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6647
6648        final IPackageManager pm = AppGlobals.getPackageManager();
6649        final String authority = grantUri.uri.getAuthority();
6650        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6651        if (pi == null) {
6652            Slog.w(TAG, "No content provider found for permission revoke: "
6653                    + grantUri.toSafeString());
6654            return;
6655        }
6656
6657        // Does the caller have this permission on the URI?
6658        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6659            // Right now, if you are not the original owner of the permission,
6660            // you are not allowed to revoke it.
6661            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6662                throw new SecurityException("Uid " + callingUid
6663                        + " does not have permission to uri " + grantUri);
6664            //}
6665        }
6666
6667        boolean persistChanged = false;
6668
6669        // Go through all of the permissions and remove any that match.
6670        int N = mGrantedUriPermissions.size();
6671        for (int i = 0; i < N; i++) {
6672            final int targetUid = mGrantedUriPermissions.keyAt(i);
6673            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6674
6675            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6676                final UriPermission perm = it.next();
6677                if (perm.uri.sourceUserId == grantUri.sourceUserId
6678                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6679                    if (DEBUG_URI_PERMISSION)
6680                        Slog.v(TAG,
6681                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6682                    persistChanged |= perm.revokeModes(
6683                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6684                    if (perm.modeFlags == 0) {
6685                        it.remove();
6686                    }
6687                }
6688            }
6689
6690            if (perms.isEmpty()) {
6691                mGrantedUriPermissions.remove(targetUid);
6692                N--;
6693                i--;
6694            }
6695        }
6696
6697        if (persistChanged) {
6698            schedulePersistUriGrants();
6699        }
6700    }
6701
6702    @Override
6703    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6704            int userId) {
6705        enforceNotIsolatedCaller("revokeUriPermission");
6706        synchronized(this) {
6707            final ProcessRecord r = getRecordForAppLocked(caller);
6708            if (r == null) {
6709                throw new SecurityException("Unable to find app for caller "
6710                        + caller
6711                        + " when revoking permission to uri " + uri);
6712            }
6713            if (uri == null) {
6714                Slog.w(TAG, "revokeUriPermission: null uri");
6715                return;
6716            }
6717
6718            if (!Intent.isAccessUriMode(modeFlags)) {
6719                return;
6720            }
6721
6722            final IPackageManager pm = AppGlobals.getPackageManager();
6723            final String authority = uri.getAuthority();
6724            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6725            if (pi == null) {
6726                Slog.w(TAG, "No content provider found for permission revoke: "
6727                        + uri.toSafeString());
6728                return;
6729            }
6730
6731            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6732        }
6733    }
6734
6735    /**
6736     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6737     * given package.
6738     *
6739     * @param packageName Package name to match, or {@code null} to apply to all
6740     *            packages.
6741     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6742     *            to all users.
6743     * @param persistable If persistable grants should be removed.
6744     */
6745    private void removeUriPermissionsForPackageLocked(
6746            String packageName, int userHandle, boolean persistable) {
6747        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6748            throw new IllegalArgumentException("Must narrow by either package or user");
6749        }
6750
6751        boolean persistChanged = false;
6752
6753        int N = mGrantedUriPermissions.size();
6754        for (int i = 0; i < N; i++) {
6755            final int targetUid = mGrantedUriPermissions.keyAt(i);
6756            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6757
6758            // Only inspect grants matching user
6759            if (userHandle == UserHandle.USER_ALL
6760                    || userHandle == UserHandle.getUserId(targetUid)) {
6761                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6762                    final UriPermission perm = it.next();
6763
6764                    // Only inspect grants matching package
6765                    if (packageName == null || perm.sourcePkg.equals(packageName)
6766                            || perm.targetPkg.equals(packageName)) {
6767                        persistChanged |= perm.revokeModes(
6768                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6769
6770                        // Only remove when no modes remain; any persisted grants
6771                        // will keep this alive.
6772                        if (perm.modeFlags == 0) {
6773                            it.remove();
6774                        }
6775                    }
6776                }
6777
6778                if (perms.isEmpty()) {
6779                    mGrantedUriPermissions.remove(targetUid);
6780                    N--;
6781                    i--;
6782                }
6783            }
6784        }
6785
6786        if (persistChanged) {
6787            schedulePersistUriGrants();
6788        }
6789    }
6790
6791    @Override
6792    public IBinder newUriPermissionOwner(String name) {
6793        enforceNotIsolatedCaller("newUriPermissionOwner");
6794        synchronized(this) {
6795            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6796            return owner.getExternalTokenLocked();
6797        }
6798    }
6799
6800    @Override
6801    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6802            final int modeFlags, int userId) {
6803        synchronized(this) {
6804            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6805            if (owner == null) {
6806                throw new IllegalArgumentException("Unknown owner: " + token);
6807            }
6808            if (fromUid != Binder.getCallingUid()) {
6809                if (Binder.getCallingUid() != Process.myUid()) {
6810                    // Only system code can grant URI permissions on behalf
6811                    // of other users.
6812                    throw new SecurityException("nice try");
6813                }
6814            }
6815            if (targetPkg == null) {
6816                throw new IllegalArgumentException("null target");
6817            }
6818            if (uri == null) {
6819                throw new IllegalArgumentException("null uri");
6820            }
6821
6822            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6823                    modeFlags, owner);
6824        }
6825    }
6826
6827    @Override
6828    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6829        synchronized(this) {
6830            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6831            if (owner == null) {
6832                throw new IllegalArgumentException("Unknown owner: " + token);
6833            }
6834
6835            if (uri == null) {
6836                owner.removeUriPermissionsLocked(mode);
6837            } else {
6838                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6839            }
6840        }
6841    }
6842
6843    private void schedulePersistUriGrants() {
6844        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6845            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6846                    10 * DateUtils.SECOND_IN_MILLIS);
6847        }
6848    }
6849
6850    private void writeGrantedUriPermissions() {
6851        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6852
6853        // Snapshot permissions so we can persist without lock
6854        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6855        synchronized (this) {
6856            final int size = mGrantedUriPermissions.size();
6857            for (int i = 0; i < size; i++) {
6858                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6859                for (UriPermission perm : perms.values()) {
6860                    if (perm.persistedModeFlags != 0) {
6861                        persist.add(perm.snapshot());
6862                    }
6863                }
6864            }
6865        }
6866
6867        FileOutputStream fos = null;
6868        try {
6869            fos = mGrantFile.startWrite();
6870
6871            XmlSerializer out = new FastXmlSerializer();
6872            out.setOutput(fos, "utf-8");
6873            out.startDocument(null, true);
6874            out.startTag(null, TAG_URI_GRANTS);
6875            for (UriPermission.Snapshot perm : persist) {
6876                out.startTag(null, TAG_URI_GRANT);
6877                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6878                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6879                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6880                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6881                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6882                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6883                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6884                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6885                out.endTag(null, TAG_URI_GRANT);
6886            }
6887            out.endTag(null, TAG_URI_GRANTS);
6888            out.endDocument();
6889
6890            mGrantFile.finishWrite(fos);
6891        } catch (IOException e) {
6892            if (fos != null) {
6893                mGrantFile.failWrite(fos);
6894            }
6895        }
6896    }
6897
6898    private void readGrantedUriPermissionsLocked() {
6899        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6900
6901        final long now = System.currentTimeMillis();
6902
6903        FileInputStream fis = null;
6904        try {
6905            fis = mGrantFile.openRead();
6906            final XmlPullParser in = Xml.newPullParser();
6907            in.setInput(fis, null);
6908
6909            int type;
6910            while ((type = in.next()) != END_DOCUMENT) {
6911                final String tag = in.getName();
6912                if (type == START_TAG) {
6913                    if (TAG_URI_GRANT.equals(tag)) {
6914                        final int sourceUserId;
6915                        final int targetUserId;
6916                        final int userHandle = readIntAttribute(in,
6917                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6918                        if (userHandle != UserHandle.USER_NULL) {
6919                            // For backwards compatibility.
6920                            sourceUserId = userHandle;
6921                            targetUserId = userHandle;
6922                        } else {
6923                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6924                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6925                        }
6926                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6927                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6928                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6929                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6930                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6931                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6932
6933                        // Sanity check that provider still belongs to source package
6934                        final ProviderInfo pi = getProviderInfoLocked(
6935                                uri.getAuthority(), sourceUserId);
6936                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6937                            int targetUid = -1;
6938                            try {
6939                                targetUid = AppGlobals.getPackageManager()
6940                                        .getPackageUid(targetPkg, targetUserId);
6941                            } catch (RemoteException e) {
6942                            }
6943                            if (targetUid != -1) {
6944                                final UriPermission perm = findOrCreateUriPermissionLocked(
6945                                        sourcePkg, targetPkg, targetUid,
6946                                        new GrantUri(sourceUserId, uri, prefix));
6947                                perm.initPersistedModes(modeFlags, createdTime);
6948                            }
6949                        } else {
6950                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6951                                    + " but instead found " + pi);
6952                        }
6953                    }
6954                }
6955            }
6956        } catch (FileNotFoundException e) {
6957            // Missing grants is okay
6958        } catch (IOException e) {
6959            Log.wtf(TAG, "Failed reading Uri grants", e);
6960        } catch (XmlPullParserException e) {
6961            Log.wtf(TAG, "Failed reading Uri grants", e);
6962        } finally {
6963            IoUtils.closeQuietly(fis);
6964        }
6965    }
6966
6967    @Override
6968    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6969        enforceNotIsolatedCaller("takePersistableUriPermission");
6970
6971        Preconditions.checkFlagsArgument(modeFlags,
6972                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6973
6974        synchronized (this) {
6975            final int callingUid = Binder.getCallingUid();
6976            boolean persistChanged = false;
6977            GrantUri grantUri = new GrantUri(userId, uri, false);
6978
6979            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6980                    new GrantUri(userId, uri, false));
6981            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6982                    new GrantUri(userId, uri, true));
6983
6984            final boolean exactValid = (exactPerm != null)
6985                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6986            final boolean prefixValid = (prefixPerm != null)
6987                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6988
6989            if (!(exactValid || prefixValid)) {
6990                throw new SecurityException("No persistable permission grants found for UID "
6991                        + callingUid + " and Uri " + grantUri.toSafeString());
6992            }
6993
6994            if (exactValid) {
6995                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6996            }
6997            if (prefixValid) {
6998                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
6999            }
7000
7001            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7002
7003            if (persistChanged) {
7004                schedulePersistUriGrants();
7005            }
7006        }
7007    }
7008
7009    @Override
7010    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7011        enforceNotIsolatedCaller("releasePersistableUriPermission");
7012
7013        Preconditions.checkFlagsArgument(modeFlags,
7014                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7015
7016        synchronized (this) {
7017            final int callingUid = Binder.getCallingUid();
7018            boolean persistChanged = false;
7019
7020            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7021                    new GrantUri(userId, uri, false));
7022            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7023                    new GrantUri(userId, uri, true));
7024            if (exactPerm == null && prefixPerm == null) {
7025                throw new SecurityException("No permission grants found for UID " + callingUid
7026                        + " and Uri " + uri.toSafeString());
7027            }
7028
7029            if (exactPerm != null) {
7030                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7031                removeUriPermissionIfNeededLocked(exactPerm);
7032            }
7033            if (prefixPerm != null) {
7034                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7035                removeUriPermissionIfNeededLocked(prefixPerm);
7036            }
7037
7038            if (persistChanged) {
7039                schedulePersistUriGrants();
7040            }
7041        }
7042    }
7043
7044    /**
7045     * Prune any older {@link UriPermission} for the given UID until outstanding
7046     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7047     *
7048     * @return if any mutations occured that require persisting.
7049     */
7050    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7051        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7052        if (perms == null) return false;
7053        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7054
7055        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7056        for (UriPermission perm : perms.values()) {
7057            if (perm.persistedModeFlags != 0) {
7058                persisted.add(perm);
7059            }
7060        }
7061
7062        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7063        if (trimCount <= 0) return false;
7064
7065        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7066        for (int i = 0; i < trimCount; i++) {
7067            final UriPermission perm = persisted.get(i);
7068
7069            if (DEBUG_URI_PERMISSION) {
7070                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7071            }
7072
7073            perm.releasePersistableModes(~0);
7074            removeUriPermissionIfNeededLocked(perm);
7075        }
7076
7077        return true;
7078    }
7079
7080    @Override
7081    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7082            String packageName, boolean incoming) {
7083        enforceNotIsolatedCaller("getPersistedUriPermissions");
7084        Preconditions.checkNotNull(packageName, "packageName");
7085
7086        final int callingUid = Binder.getCallingUid();
7087        final IPackageManager pm = AppGlobals.getPackageManager();
7088        try {
7089            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7090            if (packageUid != callingUid) {
7091                throw new SecurityException(
7092                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7093            }
7094        } catch (RemoteException e) {
7095            throw new SecurityException("Failed to verify package name ownership");
7096        }
7097
7098        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7099        synchronized (this) {
7100            if (incoming) {
7101                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7102                        callingUid);
7103                if (perms == null) {
7104                    Slog.w(TAG, "No permission grants found for " + packageName);
7105                } else {
7106                    for (UriPermission perm : perms.values()) {
7107                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7108                            result.add(perm.buildPersistedPublicApiObject());
7109                        }
7110                    }
7111                }
7112            } else {
7113                final int size = mGrantedUriPermissions.size();
7114                for (int i = 0; i < size; i++) {
7115                    final ArrayMap<GrantUri, UriPermission> perms =
7116                            mGrantedUriPermissions.valueAt(i);
7117                    for (UriPermission perm : perms.values()) {
7118                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7119                            result.add(perm.buildPersistedPublicApiObject());
7120                        }
7121                    }
7122                }
7123            }
7124        }
7125        return new ParceledListSlice<android.content.UriPermission>(result);
7126    }
7127
7128    @Override
7129    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7130        synchronized (this) {
7131            ProcessRecord app =
7132                who != null ? getRecordForAppLocked(who) : null;
7133            if (app == null) return;
7134
7135            Message msg = Message.obtain();
7136            msg.what = WAIT_FOR_DEBUGGER_MSG;
7137            msg.obj = app;
7138            msg.arg1 = waiting ? 1 : 0;
7139            mHandler.sendMessage(msg);
7140        }
7141    }
7142
7143    @Override
7144    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7145        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7146        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7147        outInfo.availMem = Process.getFreeMemory();
7148        outInfo.totalMem = Process.getTotalMemory();
7149        outInfo.threshold = homeAppMem;
7150        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7151        outInfo.hiddenAppThreshold = cachedAppMem;
7152        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7153                ProcessList.SERVICE_ADJ);
7154        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7155                ProcessList.VISIBLE_APP_ADJ);
7156        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7157                ProcessList.FOREGROUND_APP_ADJ);
7158    }
7159
7160    // =========================================================
7161    // TASK MANAGEMENT
7162    // =========================================================
7163
7164    @Override
7165    public List<IAppTask> getAppTasks() {
7166        final PackageManager pm = mContext.getPackageManager();
7167        int callingUid = Binder.getCallingUid();
7168        long ident = Binder.clearCallingIdentity();
7169
7170        // Compose the list of packages for this id to test against
7171        HashSet<String> packages = new HashSet<String>();
7172        String[] uidPackages = pm.getPackagesForUid(callingUid);
7173        for (int i = 0; i < uidPackages.length; i++) {
7174            packages.add(uidPackages[i]);
7175        }
7176
7177        synchronized(this) {
7178            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7179            try {
7180                if (localLOGV) Slog.v(TAG, "getAppTasks");
7181
7182                final int N = mRecentTasks.size();
7183                for (int i = 0; i < N; i++) {
7184                    TaskRecord tr = mRecentTasks.get(i);
7185                    // Skip tasks that are not created by the caller
7186                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7187                        ActivityManager.RecentTaskInfo taskInfo =
7188                                createRecentTaskInfoFromTaskRecord(tr);
7189                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7190                        list.add(taskImpl);
7191                    }
7192                }
7193            } finally {
7194                Binder.restoreCallingIdentity(ident);
7195            }
7196            return list;
7197        }
7198    }
7199
7200    @Override
7201    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7202        final int callingUid = Binder.getCallingUid();
7203        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7204
7205        synchronized(this) {
7206            if (localLOGV) Slog.v(
7207                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7208
7209            final boolean allowed = checkCallingPermission(
7210                    android.Manifest.permission.GET_TASKS)
7211                    == PackageManager.PERMISSION_GRANTED;
7212            if (!allowed) {
7213                Slog.w(TAG, "getTasks: caller " + callingUid
7214                        + " does not hold GET_TASKS; limiting output");
7215            }
7216
7217            // TODO: Improve with MRU list from all ActivityStacks.
7218            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7219        }
7220
7221        return list;
7222    }
7223
7224    TaskRecord getMostRecentTask() {
7225        return mRecentTasks.get(0);
7226    }
7227
7228    /**
7229     * Creates a new RecentTaskInfo from a TaskRecord.
7230     */
7231    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7232        // Update the task description to reflect any changes in the task stack
7233        tr.updateTaskDescription();
7234
7235        // Compose the recent task info
7236        ActivityManager.RecentTaskInfo rti
7237                = new ActivityManager.RecentTaskInfo();
7238        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7239        rti.persistentId = tr.taskId;
7240        rti.baseIntent = new Intent(tr.getBaseIntent());
7241        rti.origActivity = tr.origActivity;
7242        rti.description = tr.lastDescription;
7243        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7244        rti.userId = tr.userId;
7245        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7246        rti.lastActiveTime = tr.lastActiveTime;
7247        return rti;
7248    }
7249
7250    @Override
7251    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7252            int flags, int userId) {
7253        final int callingUid = Binder.getCallingUid();
7254        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7255                false, true, "getRecentTasks", null);
7256
7257        synchronized (this) {
7258            final boolean allowed = checkCallingPermission(
7259                    android.Manifest.permission.GET_TASKS)
7260                    == PackageManager.PERMISSION_GRANTED;
7261            if (!allowed) {
7262                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7263                        + " does not hold GET_TASKS; limiting output");
7264            }
7265            final boolean detailed = checkCallingPermission(
7266                    android.Manifest.permission.GET_DETAILED_TASKS)
7267                    == PackageManager.PERMISSION_GRANTED;
7268
7269            IPackageManager pm = AppGlobals.getPackageManager();
7270
7271            final int N = mRecentTasks.size();
7272            ArrayList<ActivityManager.RecentTaskInfo> res
7273                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7274                            maxNum < N ? maxNum : N);
7275
7276            final Set<Integer> includedUsers;
7277            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7278                includedUsers = getProfileIdsLocked(userId);
7279            } else {
7280                includedUsers = new HashSet<Integer>();
7281            }
7282            includedUsers.add(Integer.valueOf(userId));
7283            for (int i=0; i<N && maxNum > 0; i++) {
7284                TaskRecord tr = mRecentTasks.get(i);
7285                // Only add calling user or related users recent tasks
7286                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7287
7288                // Return the entry if desired by the caller.  We always return
7289                // the first entry, because callers always expect this to be the
7290                // foreground app.  We may filter others if the caller has
7291                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7292                // we should exclude the entry.
7293
7294                if (i == 0
7295                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7296                        || (tr.intent == null)
7297                        || ((tr.intent.getFlags()
7298                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7299                    if (!allowed) {
7300                        // If the caller doesn't have the GET_TASKS permission, then only
7301                        // allow them to see a small subset of tasks -- their own and home.
7302                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7303                            continue;
7304                        }
7305                    }
7306                    if (tr.intent != null &&
7307                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7308                            != 0 && tr.getTopActivity() == null) {
7309                        // Don't include auto remove tasks that are finished or finishing.
7310                        continue;
7311                    }
7312
7313                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7314                    if (!detailed) {
7315                        rti.baseIntent.replaceExtras((Bundle)null);
7316                    }
7317
7318                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7319                        // Check whether this activity is currently available.
7320                        try {
7321                            if (rti.origActivity != null) {
7322                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7323                                        == null) {
7324                                    continue;
7325                                }
7326                            } else if (rti.baseIntent != null) {
7327                                if (pm.queryIntentActivities(rti.baseIntent,
7328                                        null, 0, userId) == null) {
7329                                    continue;
7330                                }
7331                            }
7332                        } catch (RemoteException e) {
7333                            // Will never happen.
7334                        }
7335                    }
7336
7337                    res.add(rti);
7338                    maxNum--;
7339                }
7340            }
7341            return res;
7342        }
7343    }
7344
7345    private TaskRecord recentTaskForIdLocked(int id) {
7346        final int N = mRecentTasks.size();
7347            for (int i=0; i<N; i++) {
7348                TaskRecord tr = mRecentTasks.get(i);
7349                if (tr.taskId == id) {
7350                    return tr;
7351                }
7352            }
7353            return null;
7354    }
7355
7356    @Override
7357    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7358        synchronized (this) {
7359            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7360                    "getTaskThumbnail()");
7361            TaskRecord tr = recentTaskForIdLocked(id);
7362            if (tr != null) {
7363                return tr.getTaskThumbnailLocked();
7364            }
7365        }
7366        return null;
7367    }
7368
7369    @Override
7370    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7371        synchronized (this) {
7372            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7373            if (r != null) {
7374                r.taskDescription = td;
7375                r.task.updateTaskDescription();
7376            }
7377        }
7378    }
7379
7380    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7381        if (!pr.killedByAm) {
7382            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7383            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7384                    pr.processName, pr.setAdj, reason);
7385            pr.killedByAm = true;
7386            Process.killProcessQuiet(pr.pid);
7387        }
7388    }
7389
7390    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7391        tr.disposeThumbnail();
7392        mRecentTasks.remove(tr);
7393        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7394        Intent baseIntent = new Intent(
7395                tr.intent != null ? tr.intent : tr.affinityIntent);
7396        ComponentName component = baseIntent.getComponent();
7397        if (component == null) {
7398            Slog.w(TAG, "Now component for base intent of task: " + tr);
7399            return;
7400        }
7401
7402        // Find any running services associated with this app.
7403        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7404
7405        if (killProcesses) {
7406            // Find any running processes associated with this app.
7407            final String pkg = component.getPackageName();
7408            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7409            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7410            for (int i=0; i<pmap.size(); i++) {
7411                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7412                for (int j=0; j<uids.size(); j++) {
7413                    ProcessRecord proc = uids.valueAt(j);
7414                    if (proc.userId != tr.userId) {
7415                        continue;
7416                    }
7417                    if (!proc.pkgList.containsKey(pkg)) {
7418                        continue;
7419                    }
7420                    procs.add(proc);
7421                }
7422            }
7423
7424            // Kill the running processes.
7425            for (int i=0; i<procs.size(); i++) {
7426                ProcessRecord pr = procs.get(i);
7427                if (pr == mHomeProcess) {
7428                    // Don't kill the home process along with tasks from the same package.
7429                    continue;
7430                }
7431                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7432                    killUnneededProcessLocked(pr, "remove task");
7433                } else {
7434                    pr.waitingToKill = "remove task";
7435                }
7436            }
7437        }
7438    }
7439
7440    /**
7441     * Removes the task with the specified task id.
7442     *
7443     * @param taskId Identifier of the task to be removed.
7444     * @param flags Additional operational flags.  May be 0 or
7445     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7446     * @return Returns true if the given task was found and removed.
7447     */
7448    private boolean removeTaskByIdLocked(int taskId, int flags) {
7449        TaskRecord tr = recentTaskForIdLocked(taskId);
7450        if (tr != null) {
7451            tr.removeTaskActivitiesLocked();
7452            cleanUpRemovedTaskLocked(tr, flags);
7453            if (tr.isPersistable) {
7454                notifyTaskPersisterLocked(tr, true);
7455            }
7456            return true;
7457        }
7458        return false;
7459    }
7460
7461    @Override
7462    public boolean removeTask(int taskId, int flags) {
7463        synchronized (this) {
7464            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7465                    "removeTask()");
7466            long ident = Binder.clearCallingIdentity();
7467            try {
7468                return removeTaskByIdLocked(taskId, flags);
7469            } finally {
7470                Binder.restoreCallingIdentity(ident);
7471            }
7472        }
7473    }
7474
7475    /**
7476     * TODO: Add mController hook
7477     */
7478    @Override
7479    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7480        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7481                "moveTaskToFront()");
7482
7483        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7484        synchronized(this) {
7485            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7486                    Binder.getCallingUid(), "Task to front")) {
7487                ActivityOptions.abort(options);
7488                return;
7489            }
7490            final long origId = Binder.clearCallingIdentity();
7491            try {
7492                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7493                if (task == null) {
7494                    return;
7495                }
7496                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7497                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7498                    return;
7499                }
7500                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7501                if (prev != null && prev.isRecentsActivity()) {
7502                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7503                }
7504                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7505            } finally {
7506                Binder.restoreCallingIdentity(origId);
7507            }
7508            ActivityOptions.abort(options);
7509        }
7510    }
7511
7512    @Override
7513    public void moveTaskToBack(int taskId) {
7514        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7515                "moveTaskToBack()");
7516
7517        synchronized(this) {
7518            TaskRecord tr = recentTaskForIdLocked(taskId);
7519            if (tr != null) {
7520                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7521                ActivityStack stack = tr.stack;
7522                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7523                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7524                            Binder.getCallingUid(), "Task to back")) {
7525                        return;
7526                    }
7527                }
7528                final long origId = Binder.clearCallingIdentity();
7529                try {
7530                    stack.moveTaskToBackLocked(taskId, null);
7531                } finally {
7532                    Binder.restoreCallingIdentity(origId);
7533                }
7534            }
7535        }
7536    }
7537
7538    /**
7539     * Moves an activity, and all of the other activities within the same task, to the bottom
7540     * of the history stack.  The activity's order within the task is unchanged.
7541     *
7542     * @param token A reference to the activity we wish to move
7543     * @param nonRoot If false then this only works if the activity is the root
7544     *                of a task; if true it will work for any activity in a task.
7545     * @return Returns true if the move completed, false if not.
7546     */
7547    @Override
7548    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7549        enforceNotIsolatedCaller("moveActivityTaskToBack");
7550        synchronized(this) {
7551            final long origId = Binder.clearCallingIdentity();
7552            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7553            if (taskId >= 0) {
7554                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7555            }
7556            Binder.restoreCallingIdentity(origId);
7557        }
7558        return false;
7559    }
7560
7561    @Override
7562    public void moveTaskBackwards(int task) {
7563        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7564                "moveTaskBackwards()");
7565
7566        synchronized(this) {
7567            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7568                    Binder.getCallingUid(), "Task backwards")) {
7569                return;
7570            }
7571            final long origId = Binder.clearCallingIdentity();
7572            moveTaskBackwardsLocked(task);
7573            Binder.restoreCallingIdentity(origId);
7574        }
7575    }
7576
7577    private final void moveTaskBackwardsLocked(int task) {
7578        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7579    }
7580
7581    @Override
7582    public IBinder getHomeActivityToken() throws RemoteException {
7583        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7584                "getHomeActivityToken()");
7585        synchronized (this) {
7586            return mStackSupervisor.getHomeActivityToken();
7587        }
7588    }
7589
7590    @Override
7591    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7592            IActivityContainerCallback callback) throws RemoteException {
7593        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7594                "createActivityContainer()");
7595        synchronized (this) {
7596            if (parentActivityToken == null) {
7597                throw new IllegalArgumentException("parent token must not be null");
7598            }
7599            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7600            if (r == null) {
7601                return null;
7602            }
7603            if (callback == null) {
7604                throw new IllegalArgumentException("callback must not be null");
7605            }
7606            return mStackSupervisor.createActivityContainer(r, callback);
7607        }
7608    }
7609
7610    @Override
7611    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7612        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7613                "deleteActivityContainer()");
7614        synchronized (this) {
7615            mStackSupervisor.deleteActivityContainer(container);
7616        }
7617    }
7618
7619    @Override
7620    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7621            throws RemoteException {
7622        synchronized (this) {
7623            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7624            if (stack != null) {
7625                return stack.mActivityContainer;
7626            }
7627            return null;
7628        }
7629    }
7630
7631    @Override
7632    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7633        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7634                "moveTaskToStack()");
7635        if (stackId == HOME_STACK_ID) {
7636            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7637                    new RuntimeException("here").fillInStackTrace());
7638        }
7639        synchronized (this) {
7640            long ident = Binder.clearCallingIdentity();
7641            try {
7642                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7643                        + stackId + " toTop=" + toTop);
7644                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7645            } finally {
7646                Binder.restoreCallingIdentity(ident);
7647            }
7648        }
7649    }
7650
7651    @Override
7652    public void resizeStack(int stackBoxId, Rect bounds) {
7653        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7654                "resizeStackBox()");
7655        long ident = Binder.clearCallingIdentity();
7656        try {
7657            mWindowManager.resizeStack(stackBoxId, bounds);
7658        } finally {
7659            Binder.restoreCallingIdentity(ident);
7660        }
7661    }
7662
7663    @Override
7664    public List<StackInfo> getAllStackInfos() {
7665        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7666                "getAllStackInfos()");
7667        long ident = Binder.clearCallingIdentity();
7668        try {
7669            synchronized (this) {
7670                return mStackSupervisor.getAllStackInfosLocked();
7671            }
7672        } finally {
7673            Binder.restoreCallingIdentity(ident);
7674        }
7675    }
7676
7677    @Override
7678    public StackInfo getStackInfo(int stackId) {
7679        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7680                "getStackInfo()");
7681        long ident = Binder.clearCallingIdentity();
7682        try {
7683            synchronized (this) {
7684                return mStackSupervisor.getStackInfoLocked(stackId);
7685            }
7686        } finally {
7687            Binder.restoreCallingIdentity(ident);
7688        }
7689    }
7690
7691    @Override
7692    public boolean isInHomeStack(int taskId) {
7693        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7694                "getStackInfo()");
7695        long ident = Binder.clearCallingIdentity();
7696        try {
7697            synchronized (this) {
7698                TaskRecord tr = recentTaskForIdLocked(taskId);
7699                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7700            }
7701        } finally {
7702            Binder.restoreCallingIdentity(ident);
7703        }
7704    }
7705
7706    @Override
7707    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7708        synchronized(this) {
7709            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7710        }
7711    }
7712
7713    private boolean isLockTaskAuthorized(String pkg) {
7714        final DevicePolicyManager dpm = (DevicePolicyManager)
7715                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7716        try {
7717            int uid = mContext.getPackageManager().getPackageUid(pkg,
7718                    Binder.getCallingUserHandle().getIdentifier());
7719            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7720        } catch (NameNotFoundException e) {
7721            return false;
7722        }
7723    }
7724
7725    void startLockTaskMode(TaskRecord task) {
7726        final String pkg;
7727        synchronized (this) {
7728            pkg = task.intent.getComponent().getPackageName();
7729        }
7730        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7731        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7732            final TaskRecord taskRecord = task;
7733            mHandler.post(new Runnable() {
7734                @Override
7735                public void run() {
7736                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7737                }
7738            });
7739            return;
7740        }
7741        long ident = Binder.clearCallingIdentity();
7742        try {
7743            synchronized (this) {
7744                // Since we lost lock on task, make sure it is still there.
7745                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7746                if (task != null) {
7747                    if (!isSystemInitiated
7748                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7749                        throw new IllegalArgumentException("Invalid task, not in foreground");
7750                    }
7751                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7752                }
7753            }
7754        } finally {
7755            Binder.restoreCallingIdentity(ident);
7756        }
7757    }
7758
7759    @Override
7760    public void startLockTaskMode(int taskId) {
7761        final TaskRecord task;
7762        long ident = Binder.clearCallingIdentity();
7763        try {
7764            synchronized (this) {
7765                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7766            }
7767        } finally {
7768            Binder.restoreCallingIdentity(ident);
7769        }
7770        if (task != null) {
7771            startLockTaskMode(task);
7772        }
7773    }
7774
7775    @Override
7776    public void startLockTaskMode(IBinder token) {
7777        final TaskRecord task;
7778        long ident = Binder.clearCallingIdentity();
7779        try {
7780            synchronized (this) {
7781                final ActivityRecord r = ActivityRecord.forToken(token);
7782                if (r == null) {
7783                    return;
7784                }
7785                task = r.task;
7786            }
7787        } finally {
7788            Binder.restoreCallingIdentity(ident);
7789        }
7790        if (task != null) {
7791            startLockTaskMode(task);
7792        }
7793    }
7794
7795    @Override
7796    public void startLockTaskModeOnCurrent() throws RemoteException {
7797        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7798        ActivityRecord r = null;
7799        synchronized (this) {
7800            r = mStackSupervisor.topRunningActivityLocked();
7801        }
7802        startLockTaskMode(r.task);
7803    }
7804
7805    @Override
7806    public void stopLockTaskMode() {
7807        // Verify that the user matches the package of the intent for the TaskRecord
7808        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7809        // and stopLockTaskMode.
7810        final int callingUid = Binder.getCallingUid();
7811        if (callingUid != Process.SYSTEM_UID) {
7812            try {
7813                String pkg =
7814                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7815                int uid = mContext.getPackageManager().getPackageUid(pkg,
7816                        Binder.getCallingUserHandle().getIdentifier());
7817                if (uid != callingUid) {
7818                    throw new SecurityException("Invalid uid, expected " + uid);
7819                }
7820            } catch (NameNotFoundException e) {
7821                Log.d(TAG, "stopLockTaskMode " + e);
7822                return;
7823            }
7824        }
7825        long ident = Binder.clearCallingIdentity();
7826        try {
7827            Log.d(TAG, "stopLockTaskMode");
7828            // Stop lock task
7829            synchronized (this) {
7830                mStackSupervisor.setLockTaskModeLocked(null, false);
7831            }
7832        } finally {
7833            Binder.restoreCallingIdentity(ident);
7834        }
7835    }
7836
7837    @Override
7838    public void stopLockTaskModeOnCurrent() throws RemoteException {
7839        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7840        long ident = Binder.clearCallingIdentity();
7841        try {
7842            stopLockTaskMode();
7843        } finally {
7844            Binder.restoreCallingIdentity(ident);
7845        }
7846    }
7847
7848    @Override
7849    public boolean isInLockTaskMode() {
7850        synchronized (this) {
7851            return mStackSupervisor.isInLockTaskMode();
7852        }
7853    }
7854
7855    // =========================================================
7856    // CONTENT PROVIDERS
7857    // =========================================================
7858
7859    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7860        List<ProviderInfo> providers = null;
7861        try {
7862            providers = AppGlobals.getPackageManager().
7863                queryContentProviders(app.processName, app.uid,
7864                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7865        } catch (RemoteException ex) {
7866        }
7867        if (DEBUG_MU)
7868            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7869        int userId = app.userId;
7870        if (providers != null) {
7871            int N = providers.size();
7872            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7873            for (int i=0; i<N; i++) {
7874                ProviderInfo cpi =
7875                    (ProviderInfo)providers.get(i);
7876                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7877                        cpi.name, cpi.flags);
7878                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7879                    // This is a singleton provider, but a user besides the
7880                    // default user is asking to initialize a process it runs
7881                    // in...  well, no, it doesn't actually run in this process,
7882                    // it runs in the process of the default user.  Get rid of it.
7883                    providers.remove(i);
7884                    N--;
7885                    i--;
7886                    continue;
7887                }
7888
7889                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7890                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7891                if (cpr == null) {
7892                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7893                    mProviderMap.putProviderByClass(comp, cpr);
7894                }
7895                if (DEBUG_MU)
7896                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7897                app.pubProviders.put(cpi.name, cpr);
7898                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7899                    // Don't add this if it is a platform component that is marked
7900                    // to run in multiple processes, because this is actually
7901                    // part of the framework so doesn't make sense to track as a
7902                    // separate apk in the process.
7903                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7904                            mProcessStats);
7905                }
7906                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7907            }
7908        }
7909        return providers;
7910    }
7911
7912    /**
7913     * Check if {@link ProcessRecord} has a possible chance at accessing the
7914     * given {@link ProviderInfo}. Final permission checking is always done
7915     * in {@link ContentProvider}.
7916     */
7917    private final String checkContentProviderPermissionLocked(
7918            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7919        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7920        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7921        boolean checkedGrants = false;
7922        if (checkUser) {
7923            // Looking for cross-user grants before enforcing the typical cross-users permissions
7924            if (UserHandle.getUserId(callingUid) != userId) {
7925                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7926                    return null;
7927                }
7928                checkedGrants = true;
7929            }
7930            userId = handleIncomingUser(callingPid, callingUid, userId,
7931                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7932        }
7933        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7934                cpi.applicationInfo.uid, cpi.exported)
7935                == PackageManager.PERMISSION_GRANTED) {
7936            return null;
7937        }
7938        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7939                cpi.applicationInfo.uid, cpi.exported)
7940                == PackageManager.PERMISSION_GRANTED) {
7941            return null;
7942        }
7943
7944        PathPermission[] pps = cpi.pathPermissions;
7945        if (pps != null) {
7946            int i = pps.length;
7947            while (i > 0) {
7948                i--;
7949                PathPermission pp = pps[i];
7950                String pprperm = pp.getReadPermission();
7951                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
7952                        cpi.applicationInfo.uid, cpi.exported)
7953                        == PackageManager.PERMISSION_GRANTED) {
7954                    return null;
7955                }
7956                String ppwperm = pp.getWritePermission();
7957                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
7958                        cpi.applicationInfo.uid, cpi.exported)
7959                        == PackageManager.PERMISSION_GRANTED) {
7960                    return null;
7961                }
7962            }
7963        }
7964        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7965            return null;
7966        }
7967
7968        String msg;
7969        if (!cpi.exported) {
7970            msg = "Permission Denial: opening provider " + cpi.name
7971                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7972                    + ", uid=" + callingUid + ") that is not exported from uid "
7973                    + cpi.applicationInfo.uid;
7974        } else {
7975            msg = "Permission Denial: opening provider " + cpi.name
7976                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7977                    + ", uid=" + callingUid + ") requires "
7978                    + cpi.readPermission + " or " + cpi.writePermission;
7979        }
7980        Slog.w(TAG, msg);
7981        return msg;
7982    }
7983
7984    /**
7985     * Returns if the ContentProvider has granted a uri to callingUid
7986     */
7987    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
7988        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7989        if (perms != null) {
7990            for (GrantUri grantUri : perms.keySet()) {
7991                if (grantUri.sourceUserId == userId || !checkUser) {
7992                    if (matchesProvider(grantUri.uri, cpi)) {
7993                        return true;
7994                    }
7995                }
7996            }
7997        }
7998        return false;
7999    }
8000
8001    /**
8002     * Returns true if the uri authority is one of the authorities specified in the provider.
8003     */
8004    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8005        String uriAuth = uri.getAuthority();
8006        String cpiAuth = cpi.authority;
8007        if (cpiAuth.indexOf(';') == -1) {
8008            return cpiAuth.equals(uriAuth);
8009        }
8010        String[] cpiAuths = cpiAuth.split(";");
8011        int length = cpiAuths.length;
8012        for (int i = 0; i < length; i++) {
8013            if (cpiAuths[i].equals(uriAuth)) return true;
8014        }
8015        return false;
8016    }
8017
8018    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8019            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8020        if (r != null) {
8021            for (int i=0; i<r.conProviders.size(); i++) {
8022                ContentProviderConnection conn = r.conProviders.get(i);
8023                if (conn.provider == cpr) {
8024                    if (DEBUG_PROVIDER) Slog.v(TAG,
8025                            "Adding provider requested by "
8026                            + r.processName + " from process "
8027                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8028                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8029                    if (stable) {
8030                        conn.stableCount++;
8031                        conn.numStableIncs++;
8032                    } else {
8033                        conn.unstableCount++;
8034                        conn.numUnstableIncs++;
8035                    }
8036                    return conn;
8037                }
8038            }
8039            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8040            if (stable) {
8041                conn.stableCount = 1;
8042                conn.numStableIncs = 1;
8043            } else {
8044                conn.unstableCount = 1;
8045                conn.numUnstableIncs = 1;
8046            }
8047            cpr.connections.add(conn);
8048            r.conProviders.add(conn);
8049            return conn;
8050        }
8051        cpr.addExternalProcessHandleLocked(externalProcessToken);
8052        return null;
8053    }
8054
8055    boolean decProviderCountLocked(ContentProviderConnection conn,
8056            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8057        if (conn != null) {
8058            cpr = conn.provider;
8059            if (DEBUG_PROVIDER) Slog.v(TAG,
8060                    "Removing provider requested by "
8061                    + conn.client.processName + " from process "
8062                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8063                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8064            if (stable) {
8065                conn.stableCount--;
8066            } else {
8067                conn.unstableCount--;
8068            }
8069            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8070                cpr.connections.remove(conn);
8071                conn.client.conProviders.remove(conn);
8072                return true;
8073            }
8074            return false;
8075        }
8076        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8077        return false;
8078    }
8079
8080    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8081            String name, IBinder token, boolean stable, int userId) {
8082        ContentProviderRecord cpr;
8083        ContentProviderConnection conn = null;
8084        ProviderInfo cpi = null;
8085
8086        synchronized(this) {
8087            ProcessRecord r = null;
8088            if (caller != null) {
8089                r = getRecordForAppLocked(caller);
8090                if (r == null) {
8091                    throw new SecurityException(
8092                            "Unable to find app for caller " + caller
8093                          + " (pid=" + Binder.getCallingPid()
8094                          + ") when getting content provider " + name);
8095                }
8096            }
8097
8098            boolean checkCrossUser = true;
8099
8100            // First check if this content provider has been published...
8101            cpr = mProviderMap.getProviderByName(name, userId);
8102            // If that didn't work, check if it exists for user 0 and then
8103            // verify that it's a singleton provider before using it.
8104            if (cpr == null && userId != UserHandle.USER_OWNER) {
8105                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8106                if (cpr != null) {
8107                    cpi = cpr.info;
8108                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8109                            cpi.name, cpi.flags)
8110                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8111                        userId = UserHandle.USER_OWNER;
8112                        checkCrossUser = false;
8113                    } else {
8114                        cpr = null;
8115                        cpi = null;
8116                    }
8117                }
8118            }
8119
8120            boolean providerRunning = cpr != null;
8121            if (providerRunning) {
8122                cpi = cpr.info;
8123                String msg;
8124                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8125                        != null) {
8126                    throw new SecurityException(msg);
8127                }
8128
8129                if (r != null && cpr.canRunHere(r)) {
8130                    // This provider has been published or is in the process
8131                    // of being published...  but it is also allowed to run
8132                    // in the caller's process, so don't make a connection
8133                    // and just let the caller instantiate its own instance.
8134                    ContentProviderHolder holder = cpr.newHolder(null);
8135                    // don't give caller the provider object, it needs
8136                    // to make its own.
8137                    holder.provider = null;
8138                    return holder;
8139                }
8140
8141                final long origId = Binder.clearCallingIdentity();
8142
8143                // In this case the provider instance already exists, so we can
8144                // return it right away.
8145                conn = incProviderCountLocked(r, cpr, token, stable);
8146                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8147                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8148                        // If this is a perceptible app accessing the provider,
8149                        // make sure to count it as being accessed and thus
8150                        // back up on the LRU list.  This is good because
8151                        // content providers are often expensive to start.
8152                        updateLruProcessLocked(cpr.proc, false, null);
8153                    }
8154                }
8155
8156                if (cpr.proc != null) {
8157                    if (false) {
8158                        if (cpr.name.flattenToShortString().equals(
8159                                "com.android.providers.calendar/.CalendarProvider2")) {
8160                            Slog.v(TAG, "****************** KILLING "
8161                                + cpr.name.flattenToShortString());
8162                            Process.killProcess(cpr.proc.pid);
8163                        }
8164                    }
8165                    boolean success = updateOomAdjLocked(cpr.proc);
8166                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8167                    // NOTE: there is still a race here where a signal could be
8168                    // pending on the process even though we managed to update its
8169                    // adj level.  Not sure what to do about this, but at least
8170                    // the race is now smaller.
8171                    if (!success) {
8172                        // Uh oh...  it looks like the provider's process
8173                        // has been killed on us.  We need to wait for a new
8174                        // process to be started, and make sure its death
8175                        // doesn't kill our process.
8176                        Slog.i(TAG,
8177                                "Existing provider " + cpr.name.flattenToShortString()
8178                                + " is crashing; detaching " + r);
8179                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8180                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8181                        if (!lastRef) {
8182                            // This wasn't the last ref our process had on
8183                            // the provider...  we have now been killed, bail.
8184                            return null;
8185                        }
8186                        providerRunning = false;
8187                        conn = null;
8188                    }
8189                }
8190
8191                Binder.restoreCallingIdentity(origId);
8192            }
8193
8194            boolean singleton;
8195            if (!providerRunning) {
8196                try {
8197                    cpi = AppGlobals.getPackageManager().
8198                        resolveContentProvider(name,
8199                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8200                } catch (RemoteException ex) {
8201                }
8202                if (cpi == null) {
8203                    return null;
8204                }
8205                // If the provider is a singleton AND
8206                // (it's a call within the same user || the provider is a
8207                // privileged app)
8208                // Then allow connecting to the singleton provider
8209                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8210                        cpi.name, cpi.flags)
8211                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8212                if (singleton) {
8213                    userId = UserHandle.USER_OWNER;
8214                }
8215                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8216
8217                String msg;
8218                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8219                        != null) {
8220                    throw new SecurityException(msg);
8221                }
8222
8223                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8224                        && !cpi.processName.equals("system")) {
8225                    // If this content provider does not run in the system
8226                    // process, and the system is not yet ready to run other
8227                    // processes, then fail fast instead of hanging.
8228                    throw new IllegalArgumentException(
8229                            "Attempt to launch content provider before system ready");
8230                }
8231
8232                // Make sure that the user who owns this provider is started.  If not,
8233                // we don't want to allow it to run.
8234                if (mStartedUsers.get(userId) == null) {
8235                    Slog.w(TAG, "Unable to launch app "
8236                            + cpi.applicationInfo.packageName + "/"
8237                            + cpi.applicationInfo.uid + " for provider "
8238                            + name + ": user " + userId + " is stopped");
8239                    return null;
8240                }
8241
8242                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8243                cpr = mProviderMap.getProviderByClass(comp, userId);
8244                final boolean firstClass = cpr == null;
8245                if (firstClass) {
8246                    try {
8247                        ApplicationInfo ai =
8248                            AppGlobals.getPackageManager().
8249                                getApplicationInfo(
8250                                        cpi.applicationInfo.packageName,
8251                                        STOCK_PM_FLAGS, userId);
8252                        if (ai == null) {
8253                            Slog.w(TAG, "No package info for content provider "
8254                                    + cpi.name);
8255                            return null;
8256                        }
8257                        ai = getAppInfoForUser(ai, userId);
8258                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8259                    } catch (RemoteException ex) {
8260                        // pm is in same process, this will never happen.
8261                    }
8262                }
8263
8264                if (r != null && cpr.canRunHere(r)) {
8265                    // If this is a multiprocess provider, then just return its
8266                    // info and allow the caller to instantiate it.  Only do
8267                    // this if the provider is the same user as the caller's
8268                    // process, or can run as root (so can be in any process).
8269                    return cpr.newHolder(null);
8270                }
8271
8272                if (DEBUG_PROVIDER) {
8273                    RuntimeException e = new RuntimeException("here");
8274                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8275                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8276                }
8277
8278                // This is single process, and our app is now connecting to it.
8279                // See if we are already in the process of launching this
8280                // provider.
8281                final int N = mLaunchingProviders.size();
8282                int i;
8283                for (i=0; i<N; i++) {
8284                    if (mLaunchingProviders.get(i) == cpr) {
8285                        break;
8286                    }
8287                }
8288
8289                // If the provider is not already being launched, then get it
8290                // started.
8291                if (i >= N) {
8292                    final long origId = Binder.clearCallingIdentity();
8293
8294                    try {
8295                        // Content provider is now in use, its package can't be stopped.
8296                        try {
8297                            AppGlobals.getPackageManager().setPackageStoppedState(
8298                                    cpr.appInfo.packageName, false, userId);
8299                        } catch (RemoteException e) {
8300                        } catch (IllegalArgumentException e) {
8301                            Slog.w(TAG, "Failed trying to unstop package "
8302                                    + cpr.appInfo.packageName + ": " + e);
8303                        }
8304
8305                        // Use existing process if already started
8306                        ProcessRecord proc = getProcessRecordLocked(
8307                                cpi.processName, cpr.appInfo.uid, false);
8308                        if (proc != null && proc.thread != null) {
8309                            if (DEBUG_PROVIDER) {
8310                                Slog.d(TAG, "Installing in existing process " + proc);
8311                            }
8312                            proc.pubProviders.put(cpi.name, cpr);
8313                            try {
8314                                proc.thread.scheduleInstallProvider(cpi);
8315                            } catch (RemoteException e) {
8316                            }
8317                        } else {
8318                            proc = startProcessLocked(cpi.processName,
8319                                    cpr.appInfo, false, 0, "content provider",
8320                                    new ComponentName(cpi.applicationInfo.packageName,
8321                                            cpi.name), false, false, false);
8322                            if (proc == null) {
8323                                Slog.w(TAG, "Unable to launch app "
8324                                        + cpi.applicationInfo.packageName + "/"
8325                                        + cpi.applicationInfo.uid + " for provider "
8326                                        + name + ": process is bad");
8327                                return null;
8328                            }
8329                        }
8330                        cpr.launchingApp = proc;
8331                        mLaunchingProviders.add(cpr);
8332                    } finally {
8333                        Binder.restoreCallingIdentity(origId);
8334                    }
8335                }
8336
8337                // Make sure the provider is published (the same provider class
8338                // may be published under multiple names).
8339                if (firstClass) {
8340                    mProviderMap.putProviderByClass(comp, cpr);
8341                }
8342
8343                mProviderMap.putProviderByName(name, cpr);
8344                conn = incProviderCountLocked(r, cpr, token, stable);
8345                if (conn != null) {
8346                    conn.waiting = true;
8347                }
8348            }
8349        }
8350
8351        // Wait for the provider to be published...
8352        synchronized (cpr) {
8353            while (cpr.provider == null) {
8354                if (cpr.launchingApp == null) {
8355                    Slog.w(TAG, "Unable to launch app "
8356                            + cpi.applicationInfo.packageName + "/"
8357                            + cpi.applicationInfo.uid + " for provider "
8358                            + name + ": launching app became null");
8359                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8360                            UserHandle.getUserId(cpi.applicationInfo.uid),
8361                            cpi.applicationInfo.packageName,
8362                            cpi.applicationInfo.uid, name);
8363                    return null;
8364                }
8365                try {
8366                    if (DEBUG_MU) {
8367                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8368                                + cpr.launchingApp);
8369                    }
8370                    if (conn != null) {
8371                        conn.waiting = true;
8372                    }
8373                    cpr.wait();
8374                } catch (InterruptedException ex) {
8375                } finally {
8376                    if (conn != null) {
8377                        conn.waiting = false;
8378                    }
8379                }
8380            }
8381        }
8382        return cpr != null ? cpr.newHolder(conn) : null;
8383    }
8384
8385    @Override
8386    public final ContentProviderHolder getContentProvider(
8387            IApplicationThread caller, String name, int userId, boolean stable) {
8388        enforceNotIsolatedCaller("getContentProvider");
8389        if (caller == null) {
8390            String msg = "null IApplicationThread when getting content provider "
8391                    + name;
8392            Slog.w(TAG, msg);
8393            throw new SecurityException(msg);
8394        }
8395        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8396        // with cross-user grant.
8397        return getContentProviderImpl(caller, name, null, stable, userId);
8398    }
8399
8400    public ContentProviderHolder getContentProviderExternal(
8401            String name, int userId, IBinder token) {
8402        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8403            "Do not have permission in call getContentProviderExternal()");
8404        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8405                false, true, "getContentProvider", null);
8406        return getContentProviderExternalUnchecked(name, token, userId);
8407    }
8408
8409    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8410            IBinder token, int userId) {
8411        return getContentProviderImpl(null, name, token, true, userId);
8412    }
8413
8414    /**
8415     * Drop a content provider from a ProcessRecord's bookkeeping
8416     */
8417    public void removeContentProvider(IBinder connection, boolean stable) {
8418        enforceNotIsolatedCaller("removeContentProvider");
8419        long ident = Binder.clearCallingIdentity();
8420        try {
8421            synchronized (this) {
8422                ContentProviderConnection conn;
8423                try {
8424                    conn = (ContentProviderConnection)connection;
8425                } catch (ClassCastException e) {
8426                    String msg ="removeContentProvider: " + connection
8427                            + " not a ContentProviderConnection";
8428                    Slog.w(TAG, msg);
8429                    throw new IllegalArgumentException(msg);
8430                }
8431                if (conn == null) {
8432                    throw new NullPointerException("connection is null");
8433                }
8434                if (decProviderCountLocked(conn, null, null, stable)) {
8435                    updateOomAdjLocked();
8436                }
8437            }
8438        } finally {
8439            Binder.restoreCallingIdentity(ident);
8440        }
8441    }
8442
8443    public void removeContentProviderExternal(String name, IBinder token) {
8444        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8445            "Do not have permission in call removeContentProviderExternal()");
8446        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8447    }
8448
8449    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8450        synchronized (this) {
8451            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8452            if(cpr == null) {
8453                //remove from mProvidersByClass
8454                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8455                return;
8456            }
8457
8458            //update content provider record entry info
8459            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8460            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8461            if (localCpr.hasExternalProcessHandles()) {
8462                if (localCpr.removeExternalProcessHandleLocked(token)) {
8463                    updateOomAdjLocked();
8464                } else {
8465                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8466                            + " with no external reference for token: "
8467                            + token + ".");
8468                }
8469            } else {
8470                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8471                        + " with no external references.");
8472            }
8473        }
8474    }
8475
8476    public final void publishContentProviders(IApplicationThread caller,
8477            List<ContentProviderHolder> providers) {
8478        if (providers == null) {
8479            return;
8480        }
8481
8482        enforceNotIsolatedCaller("publishContentProviders");
8483        synchronized (this) {
8484            final ProcessRecord r = getRecordForAppLocked(caller);
8485            if (DEBUG_MU)
8486                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8487            if (r == null) {
8488                throw new SecurityException(
8489                        "Unable to find app for caller " + caller
8490                      + " (pid=" + Binder.getCallingPid()
8491                      + ") when publishing content providers");
8492            }
8493
8494            final long origId = Binder.clearCallingIdentity();
8495
8496            final int N = providers.size();
8497            for (int i=0; i<N; i++) {
8498                ContentProviderHolder src = providers.get(i);
8499                if (src == null || src.info == null || src.provider == null) {
8500                    continue;
8501                }
8502                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8503                if (DEBUG_MU)
8504                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8505                if (dst != null) {
8506                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8507                    mProviderMap.putProviderByClass(comp, dst);
8508                    String names[] = dst.info.authority.split(";");
8509                    for (int j = 0; j < names.length; j++) {
8510                        mProviderMap.putProviderByName(names[j], dst);
8511                    }
8512
8513                    int NL = mLaunchingProviders.size();
8514                    int j;
8515                    for (j=0; j<NL; j++) {
8516                        if (mLaunchingProviders.get(j) == dst) {
8517                            mLaunchingProviders.remove(j);
8518                            j--;
8519                            NL--;
8520                        }
8521                    }
8522                    synchronized (dst) {
8523                        dst.provider = src.provider;
8524                        dst.proc = r;
8525                        dst.notifyAll();
8526                    }
8527                    updateOomAdjLocked(r);
8528                }
8529            }
8530
8531            Binder.restoreCallingIdentity(origId);
8532        }
8533    }
8534
8535    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8536        ContentProviderConnection conn;
8537        try {
8538            conn = (ContentProviderConnection)connection;
8539        } catch (ClassCastException e) {
8540            String msg ="refContentProvider: " + connection
8541                    + " not a ContentProviderConnection";
8542            Slog.w(TAG, msg);
8543            throw new IllegalArgumentException(msg);
8544        }
8545        if (conn == null) {
8546            throw new NullPointerException("connection is null");
8547        }
8548
8549        synchronized (this) {
8550            if (stable > 0) {
8551                conn.numStableIncs += stable;
8552            }
8553            stable = conn.stableCount + stable;
8554            if (stable < 0) {
8555                throw new IllegalStateException("stableCount < 0: " + stable);
8556            }
8557
8558            if (unstable > 0) {
8559                conn.numUnstableIncs += unstable;
8560            }
8561            unstable = conn.unstableCount + unstable;
8562            if (unstable < 0) {
8563                throw new IllegalStateException("unstableCount < 0: " + unstable);
8564            }
8565
8566            if ((stable+unstable) <= 0) {
8567                throw new IllegalStateException("ref counts can't go to zero here: stable="
8568                        + stable + " unstable=" + unstable);
8569            }
8570            conn.stableCount = stable;
8571            conn.unstableCount = unstable;
8572            return !conn.dead;
8573        }
8574    }
8575
8576    public void unstableProviderDied(IBinder connection) {
8577        ContentProviderConnection conn;
8578        try {
8579            conn = (ContentProviderConnection)connection;
8580        } catch (ClassCastException e) {
8581            String msg ="refContentProvider: " + connection
8582                    + " not a ContentProviderConnection";
8583            Slog.w(TAG, msg);
8584            throw new IllegalArgumentException(msg);
8585        }
8586        if (conn == null) {
8587            throw new NullPointerException("connection is null");
8588        }
8589
8590        // Safely retrieve the content provider associated with the connection.
8591        IContentProvider provider;
8592        synchronized (this) {
8593            provider = conn.provider.provider;
8594        }
8595
8596        if (provider == null) {
8597            // Um, yeah, we're way ahead of you.
8598            return;
8599        }
8600
8601        // Make sure the caller is being honest with us.
8602        if (provider.asBinder().pingBinder()) {
8603            // Er, no, still looks good to us.
8604            synchronized (this) {
8605                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8606                        + " says " + conn + " died, but we don't agree");
8607                return;
8608            }
8609        }
8610
8611        // Well look at that!  It's dead!
8612        synchronized (this) {
8613            if (conn.provider.provider != provider) {
8614                // But something changed...  good enough.
8615                return;
8616            }
8617
8618            ProcessRecord proc = conn.provider.proc;
8619            if (proc == null || proc.thread == null) {
8620                // Seems like the process is already cleaned up.
8621                return;
8622            }
8623
8624            // As far as we're concerned, this is just like receiving a
8625            // death notification...  just a bit prematurely.
8626            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8627                    + ") early provider death");
8628            final long ident = Binder.clearCallingIdentity();
8629            try {
8630                appDiedLocked(proc, proc.pid, proc.thread);
8631            } finally {
8632                Binder.restoreCallingIdentity(ident);
8633            }
8634        }
8635    }
8636
8637    @Override
8638    public void appNotRespondingViaProvider(IBinder connection) {
8639        enforceCallingPermission(
8640                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8641
8642        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8643        if (conn == null) {
8644            Slog.w(TAG, "ContentProviderConnection is null");
8645            return;
8646        }
8647
8648        final ProcessRecord host = conn.provider.proc;
8649        if (host == null) {
8650            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8651            return;
8652        }
8653
8654        final long token = Binder.clearCallingIdentity();
8655        try {
8656            appNotResponding(host, null, null, false, "ContentProvider not responding");
8657        } finally {
8658            Binder.restoreCallingIdentity(token);
8659        }
8660    }
8661
8662    public final void installSystemProviders() {
8663        List<ProviderInfo> providers;
8664        synchronized (this) {
8665            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8666            providers = generateApplicationProvidersLocked(app);
8667            if (providers != null) {
8668                for (int i=providers.size()-1; i>=0; i--) {
8669                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8670                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8671                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8672                                + ": not system .apk");
8673                        providers.remove(i);
8674                    }
8675                }
8676            }
8677        }
8678        if (providers != null) {
8679            mSystemThread.installSystemProviders(providers);
8680        }
8681
8682        mCoreSettingsObserver = new CoreSettingsObserver(this);
8683
8684        mUsageStatsService.monitorPackages();
8685    }
8686
8687    /**
8688     * Allows app to retrieve the MIME type of a URI without having permission
8689     * to access its content provider.
8690     *
8691     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8692     *
8693     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8694     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8695     */
8696    public String getProviderMimeType(Uri uri, int userId) {
8697        enforceNotIsolatedCaller("getProviderMimeType");
8698        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8699                userId, false, true, "getProviderMimeType", null);
8700        final String name = uri.getAuthority();
8701        final long ident = Binder.clearCallingIdentity();
8702        ContentProviderHolder holder = null;
8703
8704        try {
8705            holder = getContentProviderExternalUnchecked(name, null, userId);
8706            if (holder != null) {
8707                return holder.provider.getType(uri);
8708            }
8709        } catch (RemoteException e) {
8710            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8711            return null;
8712        } finally {
8713            if (holder != null) {
8714                removeContentProviderExternalUnchecked(name, null, userId);
8715            }
8716            Binder.restoreCallingIdentity(ident);
8717        }
8718
8719        return null;
8720    }
8721
8722    // =========================================================
8723    // GLOBAL MANAGEMENT
8724    // =========================================================
8725
8726    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8727            boolean isolated) {
8728        String proc = customProcess != null ? customProcess : info.processName;
8729        BatteryStatsImpl.Uid.Proc ps = null;
8730        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8731        int uid = info.uid;
8732        if (isolated) {
8733            int userId = UserHandle.getUserId(uid);
8734            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8735            while (true) {
8736                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8737                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8738                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8739                }
8740                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8741                mNextIsolatedProcessUid++;
8742                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8743                    // No process for this uid, use it.
8744                    break;
8745                }
8746                stepsLeft--;
8747                if (stepsLeft <= 0) {
8748                    return null;
8749                }
8750            }
8751        }
8752        return new ProcessRecord(stats, info, proc, uid);
8753    }
8754
8755    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8756            String abiOverride) {
8757        ProcessRecord app;
8758        if (!isolated) {
8759            app = getProcessRecordLocked(info.processName, info.uid, true);
8760        } else {
8761            app = null;
8762        }
8763
8764        if (app == null) {
8765            app = newProcessRecordLocked(info, null, isolated);
8766            mProcessNames.put(info.processName, app.uid, app);
8767            if (isolated) {
8768                mIsolatedProcesses.put(app.uid, app);
8769            }
8770            updateLruProcessLocked(app, false, null);
8771            updateOomAdjLocked();
8772        }
8773
8774        // This package really, really can not be stopped.
8775        try {
8776            AppGlobals.getPackageManager().setPackageStoppedState(
8777                    info.packageName, false, UserHandle.getUserId(app.uid));
8778        } catch (RemoteException e) {
8779        } catch (IllegalArgumentException e) {
8780            Slog.w(TAG, "Failed trying to unstop package "
8781                    + info.packageName + ": " + e);
8782        }
8783
8784        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8785                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8786            app.persistent = true;
8787            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8788        }
8789        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8790            mPersistentStartingProcesses.add(app);
8791            startProcessLocked(app, "added application", app.processName,
8792                    abiOverride);
8793        }
8794
8795        return app;
8796    }
8797
8798    public void unhandledBack() {
8799        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8800                "unhandledBack()");
8801
8802        synchronized(this) {
8803            final long origId = Binder.clearCallingIdentity();
8804            try {
8805                getFocusedStack().unhandledBackLocked();
8806            } finally {
8807                Binder.restoreCallingIdentity(origId);
8808            }
8809        }
8810    }
8811
8812    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8813        enforceNotIsolatedCaller("openContentUri");
8814        final int userId = UserHandle.getCallingUserId();
8815        String name = uri.getAuthority();
8816        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8817        ParcelFileDescriptor pfd = null;
8818        if (cph != null) {
8819            // We record the binder invoker's uid in thread-local storage before
8820            // going to the content provider to open the file.  Later, in the code
8821            // that handles all permissions checks, we look for this uid and use
8822            // that rather than the Activity Manager's own uid.  The effect is that
8823            // we do the check against the caller's permissions even though it looks
8824            // to the content provider like the Activity Manager itself is making
8825            // the request.
8826            sCallerIdentity.set(new Identity(
8827                    Binder.getCallingPid(), Binder.getCallingUid()));
8828            try {
8829                pfd = cph.provider.openFile(null, uri, "r", null);
8830            } catch (FileNotFoundException e) {
8831                // do nothing; pfd will be returned null
8832            } finally {
8833                // Ensure that whatever happens, we clean up the identity state
8834                sCallerIdentity.remove();
8835            }
8836
8837            // We've got the fd now, so we're done with the provider.
8838            removeContentProviderExternalUnchecked(name, null, userId);
8839        } else {
8840            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8841        }
8842        return pfd;
8843    }
8844
8845    // Actually is sleeping or shutting down or whatever else in the future
8846    // is an inactive state.
8847    public boolean isSleepingOrShuttingDown() {
8848        return mSleeping || mShuttingDown;
8849    }
8850
8851    public boolean isSleeping() {
8852        return mSleeping;
8853    }
8854
8855    void goingToSleep() {
8856        synchronized(this) {
8857            mWentToSleep = true;
8858            updateEventDispatchingLocked();
8859            goToSleepIfNeededLocked();
8860        }
8861    }
8862
8863    void finishRunningVoiceLocked() {
8864        if (mRunningVoice) {
8865            mRunningVoice = false;
8866            goToSleepIfNeededLocked();
8867        }
8868    }
8869
8870    void goToSleepIfNeededLocked() {
8871        if (mWentToSleep && !mRunningVoice) {
8872            if (!mSleeping) {
8873                mSleeping = true;
8874                mStackSupervisor.goingToSleepLocked();
8875
8876                // Initialize the wake times of all processes.
8877                checkExcessivePowerUsageLocked(false);
8878                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8879                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8880                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8881            }
8882        }
8883    }
8884
8885    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8886        mTaskPersister.notify(task, flush);
8887    }
8888
8889    @Override
8890    public boolean shutdown(int timeout) {
8891        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8892                != PackageManager.PERMISSION_GRANTED) {
8893            throw new SecurityException("Requires permission "
8894                    + android.Manifest.permission.SHUTDOWN);
8895        }
8896
8897        boolean timedout = false;
8898
8899        synchronized(this) {
8900            mShuttingDown = true;
8901            updateEventDispatchingLocked();
8902            timedout = mStackSupervisor.shutdownLocked(timeout);
8903        }
8904
8905        mAppOpsService.shutdown();
8906        mUsageStatsService.shutdown();
8907        mBatteryStatsService.shutdown();
8908        synchronized (this) {
8909            mProcessStats.shutdownLocked();
8910        }
8911        notifyTaskPersisterLocked(null, true);
8912
8913        return timedout;
8914    }
8915
8916    public final void activitySlept(IBinder token) {
8917        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8918
8919        final long origId = Binder.clearCallingIdentity();
8920
8921        synchronized (this) {
8922            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8923            if (r != null) {
8924                mStackSupervisor.activitySleptLocked(r);
8925            }
8926        }
8927
8928        Binder.restoreCallingIdentity(origId);
8929    }
8930
8931    void logLockScreen(String msg) {
8932        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8933                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8934                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8935                mStackSupervisor.mDismissKeyguardOnNextActivity);
8936    }
8937
8938    private void comeOutOfSleepIfNeededLocked() {
8939        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8940            if (mSleeping) {
8941                mSleeping = false;
8942                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8943            }
8944        }
8945    }
8946
8947    void wakingUp() {
8948        synchronized(this) {
8949            mWentToSleep = false;
8950            updateEventDispatchingLocked();
8951            comeOutOfSleepIfNeededLocked();
8952        }
8953    }
8954
8955    void startRunningVoiceLocked() {
8956        if (!mRunningVoice) {
8957            mRunningVoice = true;
8958            comeOutOfSleepIfNeededLocked();
8959        }
8960    }
8961
8962    private void updateEventDispatchingLocked() {
8963        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8964    }
8965
8966    public void setLockScreenShown(boolean shown) {
8967        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8968                != PackageManager.PERMISSION_GRANTED) {
8969            throw new SecurityException("Requires permission "
8970                    + android.Manifest.permission.DEVICE_POWER);
8971        }
8972
8973        synchronized(this) {
8974            long ident = Binder.clearCallingIdentity();
8975            try {
8976                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8977                mLockScreenShown = shown;
8978                comeOutOfSleepIfNeededLocked();
8979            } finally {
8980                Binder.restoreCallingIdentity(ident);
8981            }
8982        }
8983    }
8984
8985    public void stopAppSwitches() {
8986        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8987                != PackageManager.PERMISSION_GRANTED) {
8988            throw new SecurityException("Requires permission "
8989                    + android.Manifest.permission.STOP_APP_SWITCHES);
8990        }
8991
8992        synchronized(this) {
8993            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8994                    + APP_SWITCH_DELAY_TIME;
8995            mDidAppSwitch = false;
8996            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8997            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8998            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8999        }
9000    }
9001
9002    public void resumeAppSwitches() {
9003        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9004                != PackageManager.PERMISSION_GRANTED) {
9005            throw new SecurityException("Requires permission "
9006                    + android.Manifest.permission.STOP_APP_SWITCHES);
9007        }
9008
9009        synchronized(this) {
9010            // Note that we don't execute any pending app switches... we will
9011            // let those wait until either the timeout, or the next start
9012            // activity request.
9013            mAppSwitchesAllowedTime = 0;
9014        }
9015    }
9016
9017    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9018            String name) {
9019        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9020            return true;
9021        }
9022
9023        final int perm = checkComponentPermission(
9024                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9025                callingUid, -1, true);
9026        if (perm == PackageManager.PERMISSION_GRANTED) {
9027            return true;
9028        }
9029
9030        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9031        return false;
9032    }
9033
9034    public void setDebugApp(String packageName, boolean waitForDebugger,
9035            boolean persistent) {
9036        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9037                "setDebugApp()");
9038
9039        long ident = Binder.clearCallingIdentity();
9040        try {
9041            // Note that this is not really thread safe if there are multiple
9042            // callers into it at the same time, but that's not a situation we
9043            // care about.
9044            if (persistent) {
9045                final ContentResolver resolver = mContext.getContentResolver();
9046                Settings.Global.putString(
9047                    resolver, Settings.Global.DEBUG_APP,
9048                    packageName);
9049                Settings.Global.putInt(
9050                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9051                    waitForDebugger ? 1 : 0);
9052            }
9053
9054            synchronized (this) {
9055                if (!persistent) {
9056                    mOrigDebugApp = mDebugApp;
9057                    mOrigWaitForDebugger = mWaitForDebugger;
9058                }
9059                mDebugApp = packageName;
9060                mWaitForDebugger = waitForDebugger;
9061                mDebugTransient = !persistent;
9062                if (packageName != null) {
9063                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9064                            false, UserHandle.USER_ALL, "set debug app");
9065                }
9066            }
9067        } finally {
9068            Binder.restoreCallingIdentity(ident);
9069        }
9070    }
9071
9072    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9073        synchronized (this) {
9074            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9075            if (!isDebuggable) {
9076                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9077                    throw new SecurityException("Process not debuggable: " + app.packageName);
9078                }
9079            }
9080
9081            mOpenGlTraceApp = processName;
9082        }
9083    }
9084
9085    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9086            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9087        synchronized (this) {
9088            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9089            if (!isDebuggable) {
9090                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9091                    throw new SecurityException("Process not debuggable: " + app.packageName);
9092                }
9093            }
9094            mProfileApp = processName;
9095            mProfileFile = profileFile;
9096            if (mProfileFd != null) {
9097                try {
9098                    mProfileFd.close();
9099                } catch (IOException e) {
9100                }
9101                mProfileFd = null;
9102            }
9103            mProfileFd = profileFd;
9104            mProfileType = 0;
9105            mAutoStopProfiler = autoStopProfiler;
9106        }
9107    }
9108
9109    @Override
9110    public void setAlwaysFinish(boolean enabled) {
9111        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9112                "setAlwaysFinish()");
9113
9114        Settings.Global.putInt(
9115                mContext.getContentResolver(),
9116                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9117
9118        synchronized (this) {
9119            mAlwaysFinishActivities = enabled;
9120        }
9121    }
9122
9123    @Override
9124    public void setActivityController(IActivityController controller) {
9125        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9126                "setActivityController()");
9127        synchronized (this) {
9128            mController = controller;
9129            Watchdog.getInstance().setActivityController(controller);
9130        }
9131    }
9132
9133    @Override
9134    public void setUserIsMonkey(boolean userIsMonkey) {
9135        synchronized (this) {
9136            synchronized (mPidsSelfLocked) {
9137                final int callingPid = Binder.getCallingPid();
9138                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9139                if (precessRecord == null) {
9140                    throw new SecurityException("Unknown process: " + callingPid);
9141                }
9142                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9143                    throw new SecurityException("Only an instrumentation process "
9144                            + "with a UiAutomation can call setUserIsMonkey");
9145                }
9146            }
9147            mUserIsMonkey = userIsMonkey;
9148        }
9149    }
9150
9151    @Override
9152    public boolean isUserAMonkey() {
9153        synchronized (this) {
9154            // If there is a controller also implies the user is a monkey.
9155            return (mUserIsMonkey || mController != null);
9156        }
9157    }
9158
9159    public void requestBugReport() {
9160        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9161        SystemProperties.set("ctl.start", "bugreport");
9162    }
9163
9164    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9165        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9166    }
9167
9168    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9169        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9170            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9171        }
9172        return KEY_DISPATCHING_TIMEOUT;
9173    }
9174
9175    @Override
9176    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9177        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9178                != PackageManager.PERMISSION_GRANTED) {
9179            throw new SecurityException("Requires permission "
9180                    + android.Manifest.permission.FILTER_EVENTS);
9181        }
9182        ProcessRecord proc;
9183        long timeout;
9184        synchronized (this) {
9185            synchronized (mPidsSelfLocked) {
9186                proc = mPidsSelfLocked.get(pid);
9187            }
9188            timeout = getInputDispatchingTimeoutLocked(proc);
9189        }
9190
9191        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9192            return -1;
9193        }
9194
9195        return timeout;
9196    }
9197
9198    /**
9199     * Handle input dispatching timeouts.
9200     * Returns whether input dispatching should be aborted or not.
9201     */
9202    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9203            final ActivityRecord activity, final ActivityRecord parent,
9204            final boolean aboveSystem, String reason) {
9205        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9206                != PackageManager.PERMISSION_GRANTED) {
9207            throw new SecurityException("Requires permission "
9208                    + android.Manifest.permission.FILTER_EVENTS);
9209        }
9210
9211        final String annotation;
9212        if (reason == null) {
9213            annotation = "Input dispatching timed out";
9214        } else {
9215            annotation = "Input dispatching timed out (" + reason + ")";
9216        }
9217
9218        if (proc != null) {
9219            synchronized (this) {
9220                if (proc.debugging) {
9221                    return false;
9222                }
9223
9224                if (mDidDexOpt) {
9225                    // Give more time since we were dexopting.
9226                    mDidDexOpt = false;
9227                    return false;
9228                }
9229
9230                if (proc.instrumentationClass != null) {
9231                    Bundle info = new Bundle();
9232                    info.putString("shortMsg", "keyDispatchingTimedOut");
9233                    info.putString("longMsg", annotation);
9234                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9235                    return true;
9236                }
9237            }
9238            mHandler.post(new Runnable() {
9239                @Override
9240                public void run() {
9241                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9242                }
9243            });
9244        }
9245
9246        return true;
9247    }
9248
9249    public Bundle getAssistContextExtras(int requestType) {
9250        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9251                "getAssistContextExtras()");
9252        PendingAssistExtras pae;
9253        Bundle extras = new Bundle();
9254        synchronized (this) {
9255            ActivityRecord activity = getFocusedStack().mResumedActivity;
9256            if (activity == null) {
9257                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9258                return null;
9259            }
9260            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9261            if (activity.app == null || activity.app.thread == null) {
9262                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9263                return extras;
9264            }
9265            if (activity.app.pid == Binder.getCallingPid()) {
9266                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9267                return extras;
9268            }
9269            pae = new PendingAssistExtras(activity);
9270            try {
9271                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9272                        requestType);
9273                mPendingAssistExtras.add(pae);
9274                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9275            } catch (RemoteException e) {
9276                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9277                return extras;
9278            }
9279        }
9280        synchronized (pae) {
9281            while (!pae.haveResult) {
9282                try {
9283                    pae.wait();
9284                } catch (InterruptedException e) {
9285                }
9286            }
9287            if (pae.result != null) {
9288                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9289            }
9290        }
9291        synchronized (this) {
9292            mPendingAssistExtras.remove(pae);
9293            mHandler.removeCallbacks(pae);
9294        }
9295        return extras;
9296    }
9297
9298    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9299        PendingAssistExtras pae = (PendingAssistExtras)token;
9300        synchronized (pae) {
9301            pae.result = extras;
9302            pae.haveResult = true;
9303            pae.notifyAll();
9304        }
9305    }
9306
9307    public void registerProcessObserver(IProcessObserver observer) {
9308        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9309                "registerProcessObserver()");
9310        synchronized (this) {
9311            mProcessObservers.register(observer);
9312        }
9313    }
9314
9315    @Override
9316    public void unregisterProcessObserver(IProcessObserver observer) {
9317        synchronized (this) {
9318            mProcessObservers.unregister(observer);
9319        }
9320    }
9321
9322    @Override
9323    public boolean convertFromTranslucent(IBinder token) {
9324        final long origId = Binder.clearCallingIdentity();
9325        try {
9326            synchronized (this) {
9327                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9328                if (r == null) {
9329                    return false;
9330                }
9331                if (r.changeWindowTranslucency(true)) {
9332                    mWindowManager.setAppFullscreen(token, true);
9333                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9334                    return true;
9335                }
9336                return false;
9337            }
9338        } finally {
9339            Binder.restoreCallingIdentity(origId);
9340        }
9341    }
9342
9343    @Override
9344    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9345        final long origId = Binder.clearCallingIdentity();
9346        try {
9347            synchronized (this) {
9348                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9349                if (r == null) {
9350                    return false;
9351                }
9352                if (r.changeWindowTranslucency(false)) {
9353                    r.task.stack.convertToTranslucent(r, options);
9354                    mWindowManager.setAppFullscreen(token, false);
9355                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9356                    return true;
9357                }
9358                return false;
9359            }
9360        } finally {
9361            Binder.restoreCallingIdentity(origId);
9362        }
9363    }
9364
9365    @Override
9366    public ActivityOptions getActivityOptions(IBinder token) {
9367        final long origId = Binder.clearCallingIdentity();
9368        try {
9369            synchronized (this) {
9370                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9371                if (r != null) {
9372                    final ActivityOptions activityOptions = r.pendingOptions;
9373                    r.pendingOptions = null;
9374                    return activityOptions;
9375                }
9376                return null;
9377            }
9378        } finally {
9379            Binder.restoreCallingIdentity(origId);
9380        }
9381    }
9382
9383    @Override
9384    public void setImmersive(IBinder token, boolean immersive) {
9385        synchronized(this) {
9386            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9387            if (r == null) {
9388                throw new IllegalArgumentException();
9389            }
9390            r.immersive = immersive;
9391
9392            // update associated state if we're frontmost
9393            if (r == mFocusedActivity) {
9394                if (DEBUG_IMMERSIVE) {
9395                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9396                }
9397                applyUpdateLockStateLocked(r);
9398            }
9399        }
9400    }
9401
9402    @Override
9403    public boolean isImmersive(IBinder token) {
9404        synchronized (this) {
9405            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9406            if (r == null) {
9407                throw new IllegalArgumentException();
9408            }
9409            return r.immersive;
9410        }
9411    }
9412
9413    public boolean isTopActivityImmersive() {
9414        enforceNotIsolatedCaller("startActivity");
9415        synchronized (this) {
9416            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9417            return (r != null) ? r.immersive : false;
9418        }
9419    }
9420
9421    public final void enterSafeMode() {
9422        synchronized(this) {
9423            // It only makes sense to do this before the system is ready
9424            // and started launching other packages.
9425            if (!mSystemReady) {
9426                try {
9427                    AppGlobals.getPackageManager().enterSafeMode();
9428                } catch (RemoteException e) {
9429                }
9430            }
9431
9432            mSafeMode = true;
9433        }
9434    }
9435
9436    public final void showSafeModeOverlay() {
9437        View v = LayoutInflater.from(mContext).inflate(
9438                com.android.internal.R.layout.safe_mode, null);
9439        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9440        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9441        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9442        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9443        lp.gravity = Gravity.BOTTOM | Gravity.START;
9444        lp.format = v.getBackground().getOpacity();
9445        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9446                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9447        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9448        ((WindowManager)mContext.getSystemService(
9449                Context.WINDOW_SERVICE)).addView(v, lp);
9450    }
9451
9452    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9453        if (!(sender instanceof PendingIntentRecord)) {
9454            return;
9455        }
9456        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9457        synchronized (stats) {
9458            if (mBatteryStatsService.isOnBattery()) {
9459                mBatteryStatsService.enforceCallingPermission();
9460                PendingIntentRecord rec = (PendingIntentRecord)sender;
9461                int MY_UID = Binder.getCallingUid();
9462                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9463                BatteryStatsImpl.Uid.Pkg pkg =
9464                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9465                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9466                pkg.incWakeupsLocked();
9467            }
9468        }
9469    }
9470
9471    public boolean killPids(int[] pids, String pReason, boolean secure) {
9472        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9473            throw new SecurityException("killPids only available to the system");
9474        }
9475        String reason = (pReason == null) ? "Unknown" : pReason;
9476        // XXX Note: don't acquire main activity lock here, because the window
9477        // manager calls in with its locks held.
9478
9479        boolean killed = false;
9480        synchronized (mPidsSelfLocked) {
9481            int[] types = new int[pids.length];
9482            int worstType = 0;
9483            for (int i=0; i<pids.length; i++) {
9484                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9485                if (proc != null) {
9486                    int type = proc.setAdj;
9487                    types[i] = type;
9488                    if (type > worstType) {
9489                        worstType = type;
9490                    }
9491                }
9492            }
9493
9494            // If the worst oom_adj is somewhere in the cached proc LRU range,
9495            // then constrain it so we will kill all cached procs.
9496            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9497                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9498                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9499            }
9500
9501            // If this is not a secure call, don't let it kill processes that
9502            // are important.
9503            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9504                worstType = ProcessList.SERVICE_ADJ;
9505            }
9506
9507            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9508            for (int i=0; i<pids.length; i++) {
9509                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9510                if (proc == null) {
9511                    continue;
9512                }
9513                int adj = proc.setAdj;
9514                if (adj >= worstType && !proc.killedByAm) {
9515                    killUnneededProcessLocked(proc, reason);
9516                    killed = true;
9517                }
9518            }
9519        }
9520        return killed;
9521    }
9522
9523    @Override
9524    public void killUid(int uid, String reason) {
9525        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9526            throw new SecurityException("killUid only available to the system");
9527        }
9528        synchronized (this) {
9529            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9530                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9531                    reason != null ? reason : "kill uid");
9532        }
9533    }
9534
9535    @Override
9536    public boolean killProcessesBelowForeground(String reason) {
9537        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9538            throw new SecurityException("killProcessesBelowForeground() only available to system");
9539        }
9540
9541        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9542    }
9543
9544    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9545        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9546            throw new SecurityException("killProcessesBelowAdj() only available to system");
9547        }
9548
9549        boolean killed = false;
9550        synchronized (mPidsSelfLocked) {
9551            final int size = mPidsSelfLocked.size();
9552            for (int i = 0; i < size; i++) {
9553                final int pid = mPidsSelfLocked.keyAt(i);
9554                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9555                if (proc == null) continue;
9556
9557                final int adj = proc.setAdj;
9558                if (adj > belowAdj && !proc.killedByAm) {
9559                    killUnneededProcessLocked(proc, reason);
9560                    killed = true;
9561                }
9562            }
9563        }
9564        return killed;
9565    }
9566
9567    @Override
9568    public void hang(final IBinder who, boolean allowRestart) {
9569        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9570                != PackageManager.PERMISSION_GRANTED) {
9571            throw new SecurityException("Requires permission "
9572                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9573        }
9574
9575        final IBinder.DeathRecipient death = new DeathRecipient() {
9576            @Override
9577            public void binderDied() {
9578                synchronized (this) {
9579                    notifyAll();
9580                }
9581            }
9582        };
9583
9584        try {
9585            who.linkToDeath(death, 0);
9586        } catch (RemoteException e) {
9587            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9588            return;
9589        }
9590
9591        synchronized (this) {
9592            Watchdog.getInstance().setAllowRestart(allowRestart);
9593            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9594            synchronized (death) {
9595                while (who.isBinderAlive()) {
9596                    try {
9597                        death.wait();
9598                    } catch (InterruptedException e) {
9599                    }
9600                }
9601            }
9602            Watchdog.getInstance().setAllowRestart(true);
9603        }
9604    }
9605
9606    @Override
9607    public void restart() {
9608        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9609                != PackageManager.PERMISSION_GRANTED) {
9610            throw new SecurityException("Requires permission "
9611                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9612        }
9613
9614        Log.i(TAG, "Sending shutdown broadcast...");
9615
9616        BroadcastReceiver br = new BroadcastReceiver() {
9617            @Override public void onReceive(Context context, Intent intent) {
9618                // Now the broadcast is done, finish up the low-level shutdown.
9619                Log.i(TAG, "Shutting down activity manager...");
9620                shutdown(10000);
9621                Log.i(TAG, "Shutdown complete, restarting!");
9622                Process.killProcess(Process.myPid());
9623                System.exit(10);
9624            }
9625        };
9626
9627        // First send the high-level shut down broadcast.
9628        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9629        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9630        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9631        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9632        mContext.sendOrderedBroadcastAsUser(intent,
9633                UserHandle.ALL, null, br, mHandler, 0, null, null);
9634        */
9635        br.onReceive(mContext, intent);
9636    }
9637
9638    private long getLowRamTimeSinceIdle(long now) {
9639        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9640    }
9641
9642    @Override
9643    public void performIdleMaintenance() {
9644        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9645                != PackageManager.PERMISSION_GRANTED) {
9646            throw new SecurityException("Requires permission "
9647                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9648        }
9649
9650        synchronized (this) {
9651            final long now = SystemClock.uptimeMillis();
9652            final long timeSinceLastIdle = now - mLastIdleTime;
9653            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9654            mLastIdleTime = now;
9655            mLowRamTimeSinceLastIdle = 0;
9656            if (mLowRamStartTime != 0) {
9657                mLowRamStartTime = now;
9658            }
9659
9660            StringBuilder sb = new StringBuilder(128);
9661            sb.append("Idle maintenance over ");
9662            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9663            sb.append(" low RAM for ");
9664            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9665            Slog.i(TAG, sb.toString());
9666
9667            // If at least 1/3 of our time since the last idle period has been spent
9668            // with RAM low, then we want to kill processes.
9669            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9670
9671            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9672                ProcessRecord proc = mLruProcesses.get(i);
9673                if (proc.notCachedSinceIdle) {
9674                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9675                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9676                        if (doKilling && proc.initialIdlePss != 0
9677                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9678                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9679                                    + " from " + proc.initialIdlePss + ")");
9680                        }
9681                    }
9682                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9683                    proc.notCachedSinceIdle = true;
9684                    proc.initialIdlePss = 0;
9685                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9686                            isSleeping(), now);
9687                }
9688            }
9689
9690            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9691            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9692        }
9693    }
9694
9695    private void retrieveSettings() {
9696        final ContentResolver resolver = mContext.getContentResolver();
9697        String debugApp = Settings.Global.getString(
9698            resolver, Settings.Global.DEBUG_APP);
9699        boolean waitForDebugger = Settings.Global.getInt(
9700            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9701        boolean alwaysFinishActivities = Settings.Global.getInt(
9702            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9703        boolean forceRtl = Settings.Global.getInt(
9704                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9705        // Transfer any global setting for forcing RTL layout, into a System Property
9706        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9707
9708        Configuration configuration = new Configuration();
9709        Settings.System.getConfiguration(resolver, configuration);
9710        if (forceRtl) {
9711            // This will take care of setting the correct layout direction flags
9712            configuration.setLayoutDirection(configuration.locale);
9713        }
9714
9715        synchronized (this) {
9716            mDebugApp = mOrigDebugApp = debugApp;
9717            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9718            mAlwaysFinishActivities = alwaysFinishActivities;
9719            // This happens before any activities are started, so we can
9720            // change mConfiguration in-place.
9721            updateConfigurationLocked(configuration, null, false, true);
9722            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9723        }
9724    }
9725
9726    public boolean testIsSystemReady() {
9727        // no need to synchronize(this) just to read & return the value
9728        return mSystemReady;
9729    }
9730
9731    private static File getCalledPreBootReceiversFile() {
9732        File dataDir = Environment.getDataDirectory();
9733        File systemDir = new File(dataDir, "system");
9734        File fname = new File(systemDir, "called_pre_boots.dat");
9735        return fname;
9736    }
9737
9738    static final int LAST_DONE_VERSION = 10000;
9739
9740    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9741        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9742        File file = getCalledPreBootReceiversFile();
9743        FileInputStream fis = null;
9744        try {
9745            fis = new FileInputStream(file);
9746            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9747            int fvers = dis.readInt();
9748            if (fvers == LAST_DONE_VERSION) {
9749                String vers = dis.readUTF();
9750                String codename = dis.readUTF();
9751                String build = dis.readUTF();
9752                if (android.os.Build.VERSION.RELEASE.equals(vers)
9753                        && android.os.Build.VERSION.CODENAME.equals(codename)
9754                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9755                    int num = dis.readInt();
9756                    while (num > 0) {
9757                        num--;
9758                        String pkg = dis.readUTF();
9759                        String cls = dis.readUTF();
9760                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9761                    }
9762                }
9763            }
9764        } catch (FileNotFoundException e) {
9765        } catch (IOException e) {
9766            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9767        } finally {
9768            if (fis != null) {
9769                try {
9770                    fis.close();
9771                } catch (IOException e) {
9772                }
9773            }
9774        }
9775        return lastDoneReceivers;
9776    }
9777
9778    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9779        File file = getCalledPreBootReceiversFile();
9780        FileOutputStream fos = null;
9781        DataOutputStream dos = null;
9782        try {
9783            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9784            fos = new FileOutputStream(file);
9785            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9786            dos.writeInt(LAST_DONE_VERSION);
9787            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9788            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9789            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9790            dos.writeInt(list.size());
9791            for (int i=0; i<list.size(); i++) {
9792                dos.writeUTF(list.get(i).getPackageName());
9793                dos.writeUTF(list.get(i).getClassName());
9794            }
9795        } catch (IOException e) {
9796            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9797            file.delete();
9798        } finally {
9799            FileUtils.sync(fos);
9800            if (dos != null) {
9801                try {
9802                    dos.close();
9803                } catch (IOException e) {
9804                    // TODO Auto-generated catch block
9805                    e.printStackTrace();
9806                }
9807            }
9808        }
9809    }
9810
9811    public void systemReady(final Runnable goingCallback) {
9812        synchronized(this) {
9813            if (mSystemReady) {
9814                if (goingCallback != null) goingCallback.run();
9815                return;
9816            }
9817
9818            if (mRecentTasks == null) {
9819                mRecentTasks = mTaskPersister.restoreTasksLocked();
9820                if (!mRecentTasks.isEmpty()) {
9821                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9822                }
9823                mTaskPersister.startPersisting();
9824            }
9825
9826            // Check to see if there are any update receivers to run.
9827            if (!mDidUpdate) {
9828                if (mWaitingUpdate) {
9829                    return;
9830                }
9831                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9832                List<ResolveInfo> ris = null;
9833                try {
9834                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9835                            intent, null, 0, 0);
9836                } catch (RemoteException e) {
9837                }
9838                if (ris != null) {
9839                    for (int i=ris.size()-1; i>=0; i--) {
9840                        if ((ris.get(i).activityInfo.applicationInfo.flags
9841                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9842                            ris.remove(i);
9843                        }
9844                    }
9845                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9846
9847                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9848
9849                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9850                    for (int i=0; i<ris.size(); i++) {
9851                        ActivityInfo ai = ris.get(i).activityInfo;
9852                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9853                        if (lastDoneReceivers.contains(comp)) {
9854                            // We already did the pre boot receiver for this app with the current
9855                            // platform version, so don't do it again...
9856                            ris.remove(i);
9857                            i--;
9858                            // ...however, do keep it as one that has been done, so we don't
9859                            // forget about it when rewriting the file of last done receivers.
9860                            doneReceivers.add(comp);
9861                        }
9862                    }
9863
9864                    final int[] users = getUsersLocked();
9865                    for (int i=0; i<ris.size(); i++) {
9866                        ActivityInfo ai = ris.get(i).activityInfo;
9867                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9868                        doneReceivers.add(comp);
9869                        intent.setComponent(comp);
9870                        for (int j=0; j<users.length; j++) {
9871                            IIntentReceiver finisher = null;
9872                            if (i == ris.size()-1 && j == users.length-1) {
9873                                finisher = new IIntentReceiver.Stub() {
9874                                    public void performReceive(Intent intent, int resultCode,
9875                                            String data, Bundle extras, boolean ordered,
9876                                            boolean sticky, int sendingUser) {
9877                                        // The raw IIntentReceiver interface is called
9878                                        // with the AM lock held, so redispatch to
9879                                        // execute our code without the lock.
9880                                        mHandler.post(new Runnable() {
9881                                            public void run() {
9882                                                synchronized (ActivityManagerService.this) {
9883                                                    mDidUpdate = true;
9884                                                }
9885                                                writeLastDonePreBootReceivers(doneReceivers);
9886                                                showBootMessage(mContext.getText(
9887                                                        R.string.android_upgrading_complete),
9888                                                        false);
9889                                                systemReady(goingCallback);
9890                                            }
9891                                        });
9892                                    }
9893                                };
9894                            }
9895                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9896                                    + " for user " + users[j]);
9897                            broadcastIntentLocked(null, null, intent, null, finisher,
9898                                    0, null, null, null, AppOpsManager.OP_NONE,
9899                                    true, false, MY_PID, Process.SYSTEM_UID,
9900                                    users[j]);
9901                            if (finisher != null) {
9902                                mWaitingUpdate = true;
9903                            }
9904                        }
9905                    }
9906                }
9907                if (mWaitingUpdate) {
9908                    return;
9909                }
9910                mDidUpdate = true;
9911            }
9912
9913            mAppOpsService.systemReady();
9914            mUsageStatsService.systemReady();
9915            mSystemReady = true;
9916        }
9917
9918        ArrayList<ProcessRecord> procsToKill = null;
9919        synchronized(mPidsSelfLocked) {
9920            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9921                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9922                if (!isAllowedWhileBooting(proc.info)){
9923                    if (procsToKill == null) {
9924                        procsToKill = new ArrayList<ProcessRecord>();
9925                    }
9926                    procsToKill.add(proc);
9927                }
9928            }
9929        }
9930
9931        synchronized(this) {
9932            if (procsToKill != null) {
9933                for (int i=procsToKill.size()-1; i>=0; i--) {
9934                    ProcessRecord proc = procsToKill.get(i);
9935                    Slog.i(TAG, "Removing system update proc: " + proc);
9936                    removeProcessLocked(proc, true, false, "system update done");
9937                }
9938            }
9939
9940            // Now that we have cleaned up any update processes, we
9941            // are ready to start launching real processes and know that
9942            // we won't trample on them any more.
9943            mProcessesReady = true;
9944        }
9945
9946        Slog.i(TAG, "System now ready");
9947        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9948            SystemClock.uptimeMillis());
9949
9950        synchronized(this) {
9951            // Make sure we have no pre-ready processes sitting around.
9952
9953            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9954                ResolveInfo ri = mContext.getPackageManager()
9955                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9956                                STOCK_PM_FLAGS);
9957                CharSequence errorMsg = null;
9958                if (ri != null) {
9959                    ActivityInfo ai = ri.activityInfo;
9960                    ApplicationInfo app = ai.applicationInfo;
9961                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9962                        mTopAction = Intent.ACTION_FACTORY_TEST;
9963                        mTopData = null;
9964                        mTopComponent = new ComponentName(app.packageName,
9965                                ai.name);
9966                    } else {
9967                        errorMsg = mContext.getResources().getText(
9968                                com.android.internal.R.string.factorytest_not_system);
9969                    }
9970                } else {
9971                    errorMsg = mContext.getResources().getText(
9972                            com.android.internal.R.string.factorytest_no_action);
9973                }
9974                if (errorMsg != null) {
9975                    mTopAction = null;
9976                    mTopData = null;
9977                    mTopComponent = null;
9978                    Message msg = Message.obtain();
9979                    msg.what = SHOW_FACTORY_ERROR_MSG;
9980                    msg.getData().putCharSequence("msg", errorMsg);
9981                    mHandler.sendMessage(msg);
9982                }
9983            }
9984        }
9985
9986        retrieveSettings();
9987
9988        synchronized (this) {
9989            readGrantedUriPermissionsLocked();
9990        }
9991
9992        if (goingCallback != null) goingCallback.run();
9993
9994        mSystemServiceManager.startUser(mCurrentUserId);
9995
9996        synchronized (this) {
9997            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9998                try {
9999                    List apps = AppGlobals.getPackageManager().
10000                        getPersistentApplications(STOCK_PM_FLAGS);
10001                    if (apps != null) {
10002                        int N = apps.size();
10003                        int i;
10004                        for (i=0; i<N; i++) {
10005                            ApplicationInfo info
10006                                = (ApplicationInfo)apps.get(i);
10007                            if (info != null &&
10008                                    !info.packageName.equals("android")) {
10009                                addAppLocked(info, false, null /* ABI override */);
10010                            }
10011                        }
10012                    }
10013                } catch (RemoteException ex) {
10014                    // pm is in same process, this will never happen.
10015                }
10016            }
10017
10018            // Start up initial activity.
10019            mBooting = true;
10020
10021            try {
10022                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10023                    Message msg = Message.obtain();
10024                    msg.what = SHOW_UID_ERROR_MSG;
10025                    mHandler.sendMessage(msg);
10026                }
10027            } catch (RemoteException e) {
10028            }
10029
10030            long ident = Binder.clearCallingIdentity();
10031            try {
10032                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10033                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10034                        | Intent.FLAG_RECEIVER_FOREGROUND);
10035                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10036                broadcastIntentLocked(null, null, intent,
10037                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10038                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10039                intent = new Intent(Intent.ACTION_USER_STARTING);
10040                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10041                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10042                broadcastIntentLocked(null, null, intent,
10043                        null, new IIntentReceiver.Stub() {
10044                            @Override
10045                            public void performReceive(Intent intent, int resultCode, String data,
10046                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10047                                    throws RemoteException {
10048                            }
10049                        }, 0, null, null,
10050                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10051                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10052            } catch (Throwable t) {
10053                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10054            } finally {
10055                Binder.restoreCallingIdentity(ident);
10056            }
10057            mStackSupervisor.resumeTopActivitiesLocked();
10058            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10059        }
10060    }
10061
10062    private boolean makeAppCrashingLocked(ProcessRecord app,
10063            String shortMsg, String longMsg, String stackTrace) {
10064        app.crashing = true;
10065        app.crashingReport = generateProcessError(app,
10066                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10067        startAppProblemLocked(app);
10068        app.stopFreezingAllLocked();
10069        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10070    }
10071
10072    private void makeAppNotRespondingLocked(ProcessRecord app,
10073            String activity, String shortMsg, String longMsg) {
10074        app.notResponding = true;
10075        app.notRespondingReport = generateProcessError(app,
10076                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10077                activity, shortMsg, longMsg, null);
10078        startAppProblemLocked(app);
10079        app.stopFreezingAllLocked();
10080    }
10081
10082    /**
10083     * Generate a process error record, suitable for attachment to a ProcessRecord.
10084     *
10085     * @param app The ProcessRecord in which the error occurred.
10086     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10087     *                      ActivityManager.AppErrorStateInfo
10088     * @param activity The activity associated with the crash, if known.
10089     * @param shortMsg Short message describing the crash.
10090     * @param longMsg Long message describing the crash.
10091     * @param stackTrace Full crash stack trace, may be null.
10092     *
10093     * @return Returns a fully-formed AppErrorStateInfo record.
10094     */
10095    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10096            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10097        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10098
10099        report.condition = condition;
10100        report.processName = app.processName;
10101        report.pid = app.pid;
10102        report.uid = app.info.uid;
10103        report.tag = activity;
10104        report.shortMsg = shortMsg;
10105        report.longMsg = longMsg;
10106        report.stackTrace = stackTrace;
10107
10108        return report;
10109    }
10110
10111    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10112        synchronized (this) {
10113            app.crashing = false;
10114            app.crashingReport = null;
10115            app.notResponding = false;
10116            app.notRespondingReport = null;
10117            if (app.anrDialog == fromDialog) {
10118                app.anrDialog = null;
10119            }
10120            if (app.waitDialog == fromDialog) {
10121                app.waitDialog = null;
10122            }
10123            if (app.pid > 0 && app.pid != MY_PID) {
10124                handleAppCrashLocked(app, null, null, null);
10125                killUnneededProcessLocked(app, "user request after error");
10126            }
10127        }
10128    }
10129
10130    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10131            String stackTrace) {
10132        long now = SystemClock.uptimeMillis();
10133
10134        Long crashTime;
10135        if (!app.isolated) {
10136            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10137        } else {
10138            crashTime = null;
10139        }
10140        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10141            // This process loses!
10142            Slog.w(TAG, "Process " + app.info.processName
10143                    + " has crashed too many times: killing!");
10144            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10145                    app.userId, app.info.processName, app.uid);
10146            mStackSupervisor.handleAppCrashLocked(app);
10147            if (!app.persistent) {
10148                // We don't want to start this process again until the user
10149                // explicitly does so...  but for persistent process, we really
10150                // need to keep it running.  If a persistent process is actually
10151                // repeatedly crashing, then badness for everyone.
10152                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10153                        app.info.processName);
10154                if (!app.isolated) {
10155                    // XXX We don't have a way to mark isolated processes
10156                    // as bad, since they don't have a peristent identity.
10157                    mBadProcesses.put(app.info.processName, app.uid,
10158                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10159                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10160                }
10161                app.bad = true;
10162                app.removed = true;
10163                // Don't let services in this process be restarted and potentially
10164                // annoy the user repeatedly.  Unless it is persistent, since those
10165                // processes run critical code.
10166                removeProcessLocked(app, false, false, "crash");
10167                mStackSupervisor.resumeTopActivitiesLocked();
10168                return false;
10169            }
10170            mStackSupervisor.resumeTopActivitiesLocked();
10171        } else {
10172            mStackSupervisor.finishTopRunningActivityLocked(app);
10173        }
10174
10175        // Bump up the crash count of any services currently running in the proc.
10176        for (int i=app.services.size()-1; i>=0; i--) {
10177            // Any services running in the application need to be placed
10178            // back in the pending list.
10179            ServiceRecord sr = app.services.valueAt(i);
10180            sr.crashCount++;
10181        }
10182
10183        // If the crashing process is what we consider to be the "home process" and it has been
10184        // replaced by a third-party app, clear the package preferred activities from packages
10185        // with a home activity running in the process to prevent a repeatedly crashing app
10186        // from blocking the user to manually clear the list.
10187        final ArrayList<ActivityRecord> activities = app.activities;
10188        if (app == mHomeProcess && activities.size() > 0
10189                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10190            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10191                final ActivityRecord r = activities.get(activityNdx);
10192                if (r.isHomeActivity()) {
10193                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10194                    try {
10195                        ActivityThread.getPackageManager()
10196                                .clearPackagePreferredActivities(r.packageName);
10197                    } catch (RemoteException c) {
10198                        // pm is in same process, this will never happen.
10199                    }
10200                }
10201            }
10202        }
10203
10204        if (!app.isolated) {
10205            // XXX Can't keep track of crash times for isolated processes,
10206            // because they don't have a perisistent identity.
10207            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10208        }
10209
10210        return true;
10211    }
10212
10213    void startAppProblemLocked(ProcessRecord app) {
10214        if (app.userId == mCurrentUserId) {
10215            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10216                    mContext, app.info.packageName, app.info.flags);
10217        } else {
10218            // If this app is not running under the current user, then we
10219            // can't give it a report button because that would require
10220            // launching the report UI under a different user.
10221            app.errorReportReceiver = null;
10222        }
10223        skipCurrentReceiverLocked(app);
10224    }
10225
10226    void skipCurrentReceiverLocked(ProcessRecord app) {
10227        for (BroadcastQueue queue : mBroadcastQueues) {
10228            queue.skipCurrentReceiverLocked(app);
10229        }
10230    }
10231
10232    /**
10233     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10234     * The application process will exit immediately after this call returns.
10235     * @param app object of the crashing app, null for the system server
10236     * @param crashInfo describing the exception
10237     */
10238    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10239        ProcessRecord r = findAppProcess(app, "Crash");
10240        final String processName = app == null ? "system_server"
10241                : (r == null ? "unknown" : r.processName);
10242
10243        handleApplicationCrashInner("crash", r, processName, crashInfo);
10244    }
10245
10246    /* Native crash reporting uses this inner version because it needs to be somewhat
10247     * decoupled from the AM-managed cleanup lifecycle
10248     */
10249    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10250            ApplicationErrorReport.CrashInfo crashInfo) {
10251        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10252                UserHandle.getUserId(Binder.getCallingUid()), processName,
10253                r == null ? -1 : r.info.flags,
10254                crashInfo.exceptionClassName,
10255                crashInfo.exceptionMessage,
10256                crashInfo.throwFileName,
10257                crashInfo.throwLineNumber);
10258
10259        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10260
10261        crashApplication(r, crashInfo);
10262    }
10263
10264    public void handleApplicationStrictModeViolation(
10265            IBinder app,
10266            int violationMask,
10267            StrictMode.ViolationInfo info) {
10268        ProcessRecord r = findAppProcess(app, "StrictMode");
10269        if (r == null) {
10270            return;
10271        }
10272
10273        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10274            Integer stackFingerprint = info.hashCode();
10275            boolean logIt = true;
10276            synchronized (mAlreadyLoggedViolatedStacks) {
10277                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10278                    logIt = false;
10279                    // TODO: sub-sample into EventLog for these, with
10280                    // the info.durationMillis?  Then we'd get
10281                    // the relative pain numbers, without logging all
10282                    // the stack traces repeatedly.  We'd want to do
10283                    // likewise in the client code, which also does
10284                    // dup suppression, before the Binder call.
10285                } else {
10286                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10287                        mAlreadyLoggedViolatedStacks.clear();
10288                    }
10289                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10290                }
10291            }
10292            if (logIt) {
10293                logStrictModeViolationToDropBox(r, info);
10294            }
10295        }
10296
10297        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10298            AppErrorResult result = new AppErrorResult();
10299            synchronized (this) {
10300                final long origId = Binder.clearCallingIdentity();
10301
10302                Message msg = Message.obtain();
10303                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10304                HashMap<String, Object> data = new HashMap<String, Object>();
10305                data.put("result", result);
10306                data.put("app", r);
10307                data.put("violationMask", violationMask);
10308                data.put("info", info);
10309                msg.obj = data;
10310                mHandler.sendMessage(msg);
10311
10312                Binder.restoreCallingIdentity(origId);
10313            }
10314            int res = result.get();
10315            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10316        }
10317    }
10318
10319    // Depending on the policy in effect, there could be a bunch of
10320    // these in quick succession so we try to batch these together to
10321    // minimize disk writes, number of dropbox entries, and maximize
10322    // compression, by having more fewer, larger records.
10323    private void logStrictModeViolationToDropBox(
10324            ProcessRecord process,
10325            StrictMode.ViolationInfo info) {
10326        if (info == null) {
10327            return;
10328        }
10329        final boolean isSystemApp = process == null ||
10330                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10331                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10332        final String processName = process == null ? "unknown" : process.processName;
10333        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10334        final DropBoxManager dbox = (DropBoxManager)
10335                mContext.getSystemService(Context.DROPBOX_SERVICE);
10336
10337        // Exit early if the dropbox isn't configured to accept this report type.
10338        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10339
10340        boolean bufferWasEmpty;
10341        boolean needsFlush;
10342        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10343        synchronized (sb) {
10344            bufferWasEmpty = sb.length() == 0;
10345            appendDropBoxProcessHeaders(process, processName, sb);
10346            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10347            sb.append("System-App: ").append(isSystemApp).append("\n");
10348            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10349            if (info.violationNumThisLoop != 0) {
10350                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10351            }
10352            if (info.numAnimationsRunning != 0) {
10353                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10354            }
10355            if (info.broadcastIntentAction != null) {
10356                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10357            }
10358            if (info.durationMillis != -1) {
10359                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10360            }
10361            if (info.numInstances != -1) {
10362                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10363            }
10364            if (info.tags != null) {
10365                for (String tag : info.tags) {
10366                    sb.append("Span-Tag: ").append(tag).append("\n");
10367                }
10368            }
10369            sb.append("\n");
10370            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10371                sb.append(info.crashInfo.stackTrace);
10372            }
10373            sb.append("\n");
10374
10375            // Only buffer up to ~64k.  Various logging bits truncate
10376            // things at 128k.
10377            needsFlush = (sb.length() > 64 * 1024);
10378        }
10379
10380        // Flush immediately if the buffer's grown too large, or this
10381        // is a non-system app.  Non-system apps are isolated with a
10382        // different tag & policy and not batched.
10383        //
10384        // Batching is useful during internal testing with
10385        // StrictMode settings turned up high.  Without batching,
10386        // thousands of separate files could be created on boot.
10387        if (!isSystemApp || needsFlush) {
10388            new Thread("Error dump: " + dropboxTag) {
10389                @Override
10390                public void run() {
10391                    String report;
10392                    synchronized (sb) {
10393                        report = sb.toString();
10394                        sb.delete(0, sb.length());
10395                        sb.trimToSize();
10396                    }
10397                    if (report.length() != 0) {
10398                        dbox.addText(dropboxTag, report);
10399                    }
10400                }
10401            }.start();
10402            return;
10403        }
10404
10405        // System app batching:
10406        if (!bufferWasEmpty) {
10407            // An existing dropbox-writing thread is outstanding, so
10408            // we don't need to start it up.  The existing thread will
10409            // catch the buffer appends we just did.
10410            return;
10411        }
10412
10413        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10414        // (After this point, we shouldn't access AMS internal data structures.)
10415        new Thread("Error dump: " + dropboxTag) {
10416            @Override
10417            public void run() {
10418                // 5 second sleep to let stacks arrive and be batched together
10419                try {
10420                    Thread.sleep(5000);  // 5 seconds
10421                } catch (InterruptedException e) {}
10422
10423                String errorReport;
10424                synchronized (mStrictModeBuffer) {
10425                    errorReport = mStrictModeBuffer.toString();
10426                    if (errorReport.length() == 0) {
10427                        return;
10428                    }
10429                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10430                    mStrictModeBuffer.trimToSize();
10431                }
10432                dbox.addText(dropboxTag, errorReport);
10433            }
10434        }.start();
10435    }
10436
10437    /**
10438     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10439     * @param app object of the crashing app, null for the system server
10440     * @param tag reported by the caller
10441     * @param crashInfo describing the context of the error
10442     * @return true if the process should exit immediately (WTF is fatal)
10443     */
10444    public boolean handleApplicationWtf(IBinder app, String tag,
10445            ApplicationErrorReport.CrashInfo crashInfo) {
10446        ProcessRecord r = findAppProcess(app, "WTF");
10447        final String processName = app == null ? "system_server"
10448                : (r == null ? "unknown" : r.processName);
10449
10450        EventLog.writeEvent(EventLogTags.AM_WTF,
10451                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10452                processName,
10453                r == null ? -1 : r.info.flags,
10454                tag, crashInfo.exceptionMessage);
10455
10456        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10457
10458        if (r != null && r.pid != Process.myPid() &&
10459                Settings.Global.getInt(mContext.getContentResolver(),
10460                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10461            crashApplication(r, crashInfo);
10462            return true;
10463        } else {
10464            return false;
10465        }
10466    }
10467
10468    /**
10469     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10470     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10471     */
10472    private ProcessRecord findAppProcess(IBinder app, String reason) {
10473        if (app == null) {
10474            return null;
10475        }
10476
10477        synchronized (this) {
10478            final int NP = mProcessNames.getMap().size();
10479            for (int ip=0; ip<NP; ip++) {
10480                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10481                final int NA = apps.size();
10482                for (int ia=0; ia<NA; ia++) {
10483                    ProcessRecord p = apps.valueAt(ia);
10484                    if (p.thread != null && p.thread.asBinder() == app) {
10485                        return p;
10486                    }
10487                }
10488            }
10489
10490            Slog.w(TAG, "Can't find mystery application for " + reason
10491                    + " from pid=" + Binder.getCallingPid()
10492                    + " uid=" + Binder.getCallingUid() + ": " + app);
10493            return null;
10494        }
10495    }
10496
10497    /**
10498     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10499     * to append various headers to the dropbox log text.
10500     */
10501    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10502            StringBuilder sb) {
10503        // Watchdog thread ends up invoking this function (with
10504        // a null ProcessRecord) to add the stack file to dropbox.
10505        // Do not acquire a lock on this (am) in such cases, as it
10506        // could cause a potential deadlock, if and when watchdog
10507        // is invoked due to unavailability of lock on am and it
10508        // would prevent watchdog from killing system_server.
10509        if (process == null) {
10510            sb.append("Process: ").append(processName).append("\n");
10511            return;
10512        }
10513        // Note: ProcessRecord 'process' is guarded by the service
10514        // instance.  (notably process.pkgList, which could otherwise change
10515        // concurrently during execution of this method)
10516        synchronized (this) {
10517            sb.append("Process: ").append(processName).append("\n");
10518            int flags = process.info.flags;
10519            IPackageManager pm = AppGlobals.getPackageManager();
10520            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10521            for (int ip=0; ip<process.pkgList.size(); ip++) {
10522                String pkg = process.pkgList.keyAt(ip);
10523                sb.append("Package: ").append(pkg);
10524                try {
10525                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10526                    if (pi != null) {
10527                        sb.append(" v").append(pi.versionCode);
10528                        if (pi.versionName != null) {
10529                            sb.append(" (").append(pi.versionName).append(")");
10530                        }
10531                    }
10532                } catch (RemoteException e) {
10533                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10534                }
10535                sb.append("\n");
10536            }
10537        }
10538    }
10539
10540    private static String processClass(ProcessRecord process) {
10541        if (process == null || process.pid == MY_PID) {
10542            return "system_server";
10543        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10544            return "system_app";
10545        } else {
10546            return "data_app";
10547        }
10548    }
10549
10550    /**
10551     * Write a description of an error (crash, WTF, ANR) to the drop box.
10552     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10553     * @param process which caused the error, null means the system server
10554     * @param activity which triggered the error, null if unknown
10555     * @param parent activity related to the error, null if unknown
10556     * @param subject line related to the error, null if absent
10557     * @param report in long form describing the error, null if absent
10558     * @param logFile to include in the report, null if none
10559     * @param crashInfo giving an application stack trace, null if absent
10560     */
10561    public void addErrorToDropBox(String eventType,
10562            ProcessRecord process, String processName, ActivityRecord activity,
10563            ActivityRecord parent, String subject,
10564            final String report, final File logFile,
10565            final ApplicationErrorReport.CrashInfo crashInfo) {
10566        // NOTE -- this must never acquire the ActivityManagerService lock,
10567        // otherwise the watchdog may be prevented from resetting the system.
10568
10569        final String dropboxTag = processClass(process) + "_" + eventType;
10570        final DropBoxManager dbox = (DropBoxManager)
10571                mContext.getSystemService(Context.DROPBOX_SERVICE);
10572
10573        // Exit early if the dropbox isn't configured to accept this report type.
10574        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10575
10576        final StringBuilder sb = new StringBuilder(1024);
10577        appendDropBoxProcessHeaders(process, processName, sb);
10578        if (activity != null) {
10579            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10580        }
10581        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10582            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10583        }
10584        if (parent != null && parent != activity) {
10585            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10586        }
10587        if (subject != null) {
10588            sb.append("Subject: ").append(subject).append("\n");
10589        }
10590        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10591        if (Debug.isDebuggerConnected()) {
10592            sb.append("Debugger: Connected\n");
10593        }
10594        sb.append("\n");
10595
10596        // Do the rest in a worker thread to avoid blocking the caller on I/O
10597        // (After this point, we shouldn't access AMS internal data structures.)
10598        Thread worker = new Thread("Error dump: " + dropboxTag) {
10599            @Override
10600            public void run() {
10601                if (report != null) {
10602                    sb.append(report);
10603                }
10604                if (logFile != null) {
10605                    try {
10606                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10607                                    "\n\n[[TRUNCATED]]"));
10608                    } catch (IOException e) {
10609                        Slog.e(TAG, "Error reading " + logFile, e);
10610                    }
10611                }
10612                if (crashInfo != null && crashInfo.stackTrace != null) {
10613                    sb.append(crashInfo.stackTrace);
10614                }
10615
10616                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10617                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10618                if (lines > 0) {
10619                    sb.append("\n");
10620
10621                    // Merge several logcat streams, and take the last N lines
10622                    InputStreamReader input = null;
10623                    try {
10624                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10625                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10626                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10627
10628                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10629                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10630                        input = new InputStreamReader(logcat.getInputStream());
10631
10632                        int num;
10633                        char[] buf = new char[8192];
10634                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10635                    } catch (IOException e) {
10636                        Slog.e(TAG, "Error running logcat", e);
10637                    } finally {
10638                        if (input != null) try { input.close(); } catch (IOException e) {}
10639                    }
10640                }
10641
10642                dbox.addText(dropboxTag, sb.toString());
10643            }
10644        };
10645
10646        if (process == null) {
10647            // If process is null, we are being called from some internal code
10648            // and may be about to die -- run this synchronously.
10649            worker.run();
10650        } else {
10651            worker.start();
10652        }
10653    }
10654
10655    /**
10656     * Bring up the "unexpected error" dialog box for a crashing app.
10657     * Deal with edge cases (intercepts from instrumented applications,
10658     * ActivityController, error intent receivers, that sort of thing).
10659     * @param r the application crashing
10660     * @param crashInfo describing the failure
10661     */
10662    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10663        long timeMillis = System.currentTimeMillis();
10664        String shortMsg = crashInfo.exceptionClassName;
10665        String longMsg = crashInfo.exceptionMessage;
10666        String stackTrace = crashInfo.stackTrace;
10667        if (shortMsg != null && longMsg != null) {
10668            longMsg = shortMsg + ": " + longMsg;
10669        } else if (shortMsg != null) {
10670            longMsg = shortMsg;
10671        }
10672
10673        AppErrorResult result = new AppErrorResult();
10674        synchronized (this) {
10675            if (mController != null) {
10676                try {
10677                    String name = r != null ? r.processName : null;
10678                    int pid = r != null ? r.pid : Binder.getCallingPid();
10679                    if (!mController.appCrashed(name, pid,
10680                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10681                        Slog.w(TAG, "Force-killing crashed app " + name
10682                                + " at watcher's request");
10683                        Process.killProcess(pid);
10684                        return;
10685                    }
10686                } catch (RemoteException e) {
10687                    mController = null;
10688                    Watchdog.getInstance().setActivityController(null);
10689                }
10690            }
10691
10692            final long origId = Binder.clearCallingIdentity();
10693
10694            // If this process is running instrumentation, finish it.
10695            if (r != null && r.instrumentationClass != null) {
10696                Slog.w(TAG, "Error in app " + r.processName
10697                      + " running instrumentation " + r.instrumentationClass + ":");
10698                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10699                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10700                Bundle info = new Bundle();
10701                info.putString("shortMsg", shortMsg);
10702                info.putString("longMsg", longMsg);
10703                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10704                Binder.restoreCallingIdentity(origId);
10705                return;
10706            }
10707
10708            // If we can't identify the process or it's already exceeded its crash quota,
10709            // quit right away without showing a crash dialog.
10710            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10711                Binder.restoreCallingIdentity(origId);
10712                return;
10713            }
10714
10715            Message msg = Message.obtain();
10716            msg.what = SHOW_ERROR_MSG;
10717            HashMap data = new HashMap();
10718            data.put("result", result);
10719            data.put("app", r);
10720            msg.obj = data;
10721            mHandler.sendMessage(msg);
10722
10723            Binder.restoreCallingIdentity(origId);
10724        }
10725
10726        int res = result.get();
10727
10728        Intent appErrorIntent = null;
10729        synchronized (this) {
10730            if (r != null && !r.isolated) {
10731                // XXX Can't keep track of crash time for isolated processes,
10732                // since they don't have a persistent identity.
10733                mProcessCrashTimes.put(r.info.processName, r.uid,
10734                        SystemClock.uptimeMillis());
10735            }
10736            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10737                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10738            }
10739        }
10740
10741        if (appErrorIntent != null) {
10742            try {
10743                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10744            } catch (ActivityNotFoundException e) {
10745                Slog.w(TAG, "bug report receiver dissappeared", e);
10746            }
10747        }
10748    }
10749
10750    Intent createAppErrorIntentLocked(ProcessRecord r,
10751            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10752        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10753        if (report == null) {
10754            return null;
10755        }
10756        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10757        result.setComponent(r.errorReportReceiver);
10758        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10759        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10760        return result;
10761    }
10762
10763    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10764            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10765        if (r.errorReportReceiver == null) {
10766            return null;
10767        }
10768
10769        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10770            return null;
10771        }
10772
10773        ApplicationErrorReport report = new ApplicationErrorReport();
10774        report.packageName = r.info.packageName;
10775        report.installerPackageName = r.errorReportReceiver.getPackageName();
10776        report.processName = r.processName;
10777        report.time = timeMillis;
10778        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10779
10780        if (r.crashing || r.forceCrashReport) {
10781            report.type = ApplicationErrorReport.TYPE_CRASH;
10782            report.crashInfo = crashInfo;
10783        } else if (r.notResponding) {
10784            report.type = ApplicationErrorReport.TYPE_ANR;
10785            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10786
10787            report.anrInfo.activity = r.notRespondingReport.tag;
10788            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10789            report.anrInfo.info = r.notRespondingReport.longMsg;
10790        }
10791
10792        return report;
10793    }
10794
10795    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10796        enforceNotIsolatedCaller("getProcessesInErrorState");
10797        // assume our apps are happy - lazy create the list
10798        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10799
10800        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10801                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10802        int userId = UserHandle.getUserId(Binder.getCallingUid());
10803
10804        synchronized (this) {
10805
10806            // iterate across all processes
10807            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10808                ProcessRecord app = mLruProcesses.get(i);
10809                if (!allUsers && app.userId != userId) {
10810                    continue;
10811                }
10812                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10813                    // This one's in trouble, so we'll generate a report for it
10814                    // crashes are higher priority (in case there's a crash *and* an anr)
10815                    ActivityManager.ProcessErrorStateInfo report = null;
10816                    if (app.crashing) {
10817                        report = app.crashingReport;
10818                    } else if (app.notResponding) {
10819                        report = app.notRespondingReport;
10820                    }
10821
10822                    if (report != null) {
10823                        if (errList == null) {
10824                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10825                        }
10826                        errList.add(report);
10827                    } else {
10828                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10829                                " crashing = " + app.crashing +
10830                                " notResponding = " + app.notResponding);
10831                    }
10832                }
10833            }
10834        }
10835
10836        return errList;
10837    }
10838
10839    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10840        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10841            if (currApp != null) {
10842                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10843            }
10844            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10845        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10846            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10847        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10848            if (currApp != null) {
10849                currApp.lru = 0;
10850            }
10851            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10852        } else if (adj >= ProcessList.SERVICE_ADJ) {
10853            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10854        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10855            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10856        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10857            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10858        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10859            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10860        } else {
10861            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10862        }
10863    }
10864
10865    private void fillInProcMemInfo(ProcessRecord app,
10866            ActivityManager.RunningAppProcessInfo outInfo) {
10867        outInfo.pid = app.pid;
10868        outInfo.uid = app.info.uid;
10869        if (mHeavyWeightProcess == app) {
10870            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10871        }
10872        if (app.persistent) {
10873            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10874        }
10875        if (app.activities.size() > 0) {
10876            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10877        }
10878        outInfo.lastTrimLevel = app.trimMemoryLevel;
10879        int adj = app.curAdj;
10880        outInfo.importance = oomAdjToImportance(adj, outInfo);
10881        outInfo.importanceReasonCode = app.adjTypeCode;
10882        outInfo.processState = app.curProcState;
10883    }
10884
10885    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10886        enforceNotIsolatedCaller("getRunningAppProcesses");
10887        // Lazy instantiation of list
10888        List<ActivityManager.RunningAppProcessInfo> runList = null;
10889        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10890                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10891        int userId = UserHandle.getUserId(Binder.getCallingUid());
10892        synchronized (this) {
10893            // Iterate across all processes
10894            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10895                ProcessRecord app = mLruProcesses.get(i);
10896                if (!allUsers && app.userId != userId) {
10897                    continue;
10898                }
10899                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10900                    // Generate process state info for running application
10901                    ActivityManager.RunningAppProcessInfo currApp =
10902                        new ActivityManager.RunningAppProcessInfo(app.processName,
10903                                app.pid, app.getPackageList());
10904                    fillInProcMemInfo(app, currApp);
10905                    if (app.adjSource instanceof ProcessRecord) {
10906                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10907                        currApp.importanceReasonImportance = oomAdjToImportance(
10908                                app.adjSourceOom, null);
10909                    } else if (app.adjSource instanceof ActivityRecord) {
10910                        ActivityRecord r = (ActivityRecord)app.adjSource;
10911                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10912                    }
10913                    if (app.adjTarget instanceof ComponentName) {
10914                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10915                    }
10916                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10917                    //        + " lru=" + currApp.lru);
10918                    if (runList == null) {
10919                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10920                    }
10921                    runList.add(currApp);
10922                }
10923            }
10924        }
10925        return runList;
10926    }
10927
10928    public List<ApplicationInfo> getRunningExternalApplications() {
10929        enforceNotIsolatedCaller("getRunningExternalApplications");
10930        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10931        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10932        if (runningApps != null && runningApps.size() > 0) {
10933            Set<String> extList = new HashSet<String>();
10934            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10935                if (app.pkgList != null) {
10936                    for (String pkg : app.pkgList) {
10937                        extList.add(pkg);
10938                    }
10939                }
10940            }
10941            IPackageManager pm = AppGlobals.getPackageManager();
10942            for (String pkg : extList) {
10943                try {
10944                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10945                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10946                        retList.add(info);
10947                    }
10948                } catch (RemoteException e) {
10949                }
10950            }
10951        }
10952        return retList;
10953    }
10954
10955    @Override
10956    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10957        enforceNotIsolatedCaller("getMyMemoryState");
10958        synchronized (this) {
10959            ProcessRecord proc;
10960            synchronized (mPidsSelfLocked) {
10961                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10962            }
10963            fillInProcMemInfo(proc, outInfo);
10964        }
10965    }
10966
10967    @Override
10968    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10969        if (checkCallingPermission(android.Manifest.permission.DUMP)
10970                != PackageManager.PERMISSION_GRANTED) {
10971            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10972                    + Binder.getCallingPid()
10973                    + ", uid=" + Binder.getCallingUid()
10974                    + " without permission "
10975                    + android.Manifest.permission.DUMP);
10976            return;
10977        }
10978
10979        boolean dumpAll = false;
10980        boolean dumpClient = false;
10981        String dumpPackage = null;
10982
10983        int opti = 0;
10984        while (opti < args.length) {
10985            String opt = args[opti];
10986            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10987                break;
10988            }
10989            opti++;
10990            if ("-a".equals(opt)) {
10991                dumpAll = true;
10992            } else if ("-c".equals(opt)) {
10993                dumpClient = true;
10994            } else if ("-h".equals(opt)) {
10995                pw.println("Activity manager dump options:");
10996                pw.println("  [-a] [-c] [-h] [cmd] ...");
10997                pw.println("  cmd may be one of:");
10998                pw.println("    a[ctivities]: activity stack state");
10999                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11000                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11001                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11002                pw.println("    o[om]: out of memory management");
11003                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11004                pw.println("    provider [COMP_SPEC]: provider client-side state");
11005                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11006                pw.println("    service [COMP_SPEC]: service client-side state");
11007                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11008                pw.println("    all: dump all activities");
11009                pw.println("    top: dump the top activity");
11010                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11011                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11012                pw.println("    a partial substring in a component name, a");
11013                pw.println("    hex object identifier.");
11014                pw.println("  -a: include all available server state.");
11015                pw.println("  -c: include client state.");
11016                return;
11017            } else {
11018                pw.println("Unknown argument: " + opt + "; use -h for help");
11019            }
11020        }
11021
11022        long origId = Binder.clearCallingIdentity();
11023        boolean more = false;
11024        // Is the caller requesting to dump a particular piece of data?
11025        if (opti < args.length) {
11026            String cmd = args[opti];
11027            opti++;
11028            if ("activities".equals(cmd) || "a".equals(cmd)) {
11029                synchronized (this) {
11030                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11031                }
11032            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11033                String[] newArgs;
11034                String name;
11035                if (opti >= args.length) {
11036                    name = null;
11037                    newArgs = EMPTY_STRING_ARRAY;
11038                } else {
11039                    name = args[opti];
11040                    opti++;
11041                    newArgs = new String[args.length - opti];
11042                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11043                            args.length - opti);
11044                }
11045                synchronized (this) {
11046                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11047                }
11048            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11049                String[] newArgs;
11050                String name;
11051                if (opti >= args.length) {
11052                    name = null;
11053                    newArgs = EMPTY_STRING_ARRAY;
11054                } else {
11055                    name = args[opti];
11056                    opti++;
11057                    newArgs = new String[args.length - opti];
11058                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11059                            args.length - opti);
11060                }
11061                synchronized (this) {
11062                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11063                }
11064            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11065                String[] newArgs;
11066                String name;
11067                if (opti >= args.length) {
11068                    name = null;
11069                    newArgs = EMPTY_STRING_ARRAY;
11070                } else {
11071                    name = args[opti];
11072                    opti++;
11073                    newArgs = new String[args.length - opti];
11074                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11075                            args.length - opti);
11076                }
11077                synchronized (this) {
11078                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11079                }
11080            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11081                synchronized (this) {
11082                    dumpOomLocked(fd, pw, args, opti, true);
11083                }
11084            } else if ("provider".equals(cmd)) {
11085                String[] newArgs;
11086                String name;
11087                if (opti >= args.length) {
11088                    name = null;
11089                    newArgs = EMPTY_STRING_ARRAY;
11090                } else {
11091                    name = args[opti];
11092                    opti++;
11093                    newArgs = new String[args.length - opti];
11094                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11095                }
11096                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11097                    pw.println("No providers match: " + name);
11098                    pw.println("Use -h for help.");
11099                }
11100            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11101                synchronized (this) {
11102                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11103                }
11104            } else if ("service".equals(cmd)) {
11105                String[] newArgs;
11106                String name;
11107                if (opti >= args.length) {
11108                    name = null;
11109                    newArgs = EMPTY_STRING_ARRAY;
11110                } else {
11111                    name = args[opti];
11112                    opti++;
11113                    newArgs = new String[args.length - opti];
11114                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11115                            args.length - opti);
11116                }
11117                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11118                    pw.println("No services match: " + name);
11119                    pw.println("Use -h for help.");
11120                }
11121            } else if ("package".equals(cmd)) {
11122                String[] newArgs;
11123                if (opti >= args.length) {
11124                    pw.println("package: no package name specified");
11125                    pw.println("Use -h for help.");
11126                } else {
11127                    dumpPackage = args[opti];
11128                    opti++;
11129                    newArgs = new String[args.length - opti];
11130                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11131                            args.length - opti);
11132                    args = newArgs;
11133                    opti = 0;
11134                    more = true;
11135                }
11136            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11137                synchronized (this) {
11138                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11139                }
11140            } else {
11141                // Dumping a single activity?
11142                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11143                    pw.println("Bad activity command, or no activities match: " + cmd);
11144                    pw.println("Use -h for help.");
11145                }
11146            }
11147            if (!more) {
11148                Binder.restoreCallingIdentity(origId);
11149                return;
11150            }
11151        }
11152
11153        // No piece of data specified, dump everything.
11154        synchronized (this) {
11155            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11156            pw.println();
11157            if (dumpAll) {
11158                pw.println("-------------------------------------------------------------------------------");
11159            }
11160            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11161            pw.println();
11162            if (dumpAll) {
11163                pw.println("-------------------------------------------------------------------------------");
11164            }
11165            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11166            pw.println();
11167            if (dumpAll) {
11168                pw.println("-------------------------------------------------------------------------------");
11169            }
11170            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11171            pw.println();
11172            if (dumpAll) {
11173                pw.println("-------------------------------------------------------------------------------");
11174            }
11175            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11176            pw.println();
11177            if (dumpAll) {
11178                pw.println("-------------------------------------------------------------------------------");
11179            }
11180            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11181        }
11182        Binder.restoreCallingIdentity(origId);
11183    }
11184
11185    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11186            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11187        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11188
11189        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11190                dumpPackage);
11191        boolean needSep = printedAnything;
11192
11193        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11194                dumpPackage, needSep, "  mFocusedActivity: ");
11195        if (printed) {
11196            printedAnything = true;
11197            needSep = false;
11198        }
11199
11200        if (dumpPackage == null) {
11201            if (needSep) {
11202                pw.println();
11203            }
11204            needSep = true;
11205            printedAnything = true;
11206            mStackSupervisor.dump(pw, "  ");
11207        }
11208
11209        if (mRecentTasks.size() > 0) {
11210            boolean printedHeader = false;
11211
11212            final int N = mRecentTasks.size();
11213            for (int i=0; i<N; i++) {
11214                TaskRecord tr = mRecentTasks.get(i);
11215                if (dumpPackage != null) {
11216                    if (tr.realActivity == null ||
11217                            !dumpPackage.equals(tr.realActivity)) {
11218                        continue;
11219                    }
11220                }
11221                if (!printedHeader) {
11222                    if (needSep) {
11223                        pw.println();
11224                    }
11225                    pw.println("  Recent tasks:");
11226                    printedHeader = true;
11227                    printedAnything = true;
11228                }
11229                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11230                        pw.println(tr);
11231                if (dumpAll) {
11232                    mRecentTasks.get(i).dump(pw, "    ");
11233                }
11234            }
11235        }
11236
11237        if (!printedAnything) {
11238            pw.println("  (nothing)");
11239        }
11240    }
11241
11242    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11243            int opti, boolean dumpAll, String dumpPackage) {
11244        boolean needSep = false;
11245        boolean printedAnything = false;
11246        int numPers = 0;
11247
11248        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11249
11250        if (dumpAll) {
11251            final int NP = mProcessNames.getMap().size();
11252            for (int ip=0; ip<NP; ip++) {
11253                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11254                final int NA = procs.size();
11255                for (int ia=0; ia<NA; ia++) {
11256                    ProcessRecord r = procs.valueAt(ia);
11257                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11258                        continue;
11259                    }
11260                    if (!needSep) {
11261                        pw.println("  All known processes:");
11262                        needSep = true;
11263                        printedAnything = true;
11264                    }
11265                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11266                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11267                        pw.print(" "); pw.println(r);
11268                    r.dump(pw, "    ");
11269                    if (r.persistent) {
11270                        numPers++;
11271                    }
11272                }
11273            }
11274        }
11275
11276        if (mIsolatedProcesses.size() > 0) {
11277            boolean printed = false;
11278            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11279                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11280                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11281                    continue;
11282                }
11283                if (!printed) {
11284                    if (needSep) {
11285                        pw.println();
11286                    }
11287                    pw.println("  Isolated process list (sorted by uid):");
11288                    printedAnything = true;
11289                    printed = true;
11290                    needSep = true;
11291                }
11292                pw.println(String.format("%sIsolated #%2d: %s",
11293                        "    ", i, r.toString()));
11294            }
11295        }
11296
11297        if (mLruProcesses.size() > 0) {
11298            if (needSep) {
11299                pw.println();
11300            }
11301            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11302                    pw.print(" total, non-act at ");
11303                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11304                    pw.print(", non-svc at ");
11305                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11306                    pw.println("):");
11307            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11308            needSep = true;
11309            printedAnything = true;
11310        }
11311
11312        if (dumpAll || dumpPackage != null) {
11313            synchronized (mPidsSelfLocked) {
11314                boolean printed = false;
11315                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11316                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11317                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11318                        continue;
11319                    }
11320                    if (!printed) {
11321                        if (needSep) pw.println();
11322                        needSep = true;
11323                        pw.println("  PID mappings:");
11324                        printed = true;
11325                        printedAnything = true;
11326                    }
11327                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11328                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11329                }
11330            }
11331        }
11332
11333        if (mForegroundProcesses.size() > 0) {
11334            synchronized (mPidsSelfLocked) {
11335                boolean printed = false;
11336                for (int i=0; i<mForegroundProcesses.size(); i++) {
11337                    ProcessRecord r = mPidsSelfLocked.get(
11338                            mForegroundProcesses.valueAt(i).pid);
11339                    if (dumpPackage != null && (r == null
11340                            || !r.pkgList.containsKey(dumpPackage))) {
11341                        continue;
11342                    }
11343                    if (!printed) {
11344                        if (needSep) pw.println();
11345                        needSep = true;
11346                        pw.println("  Foreground Processes:");
11347                        printed = true;
11348                        printedAnything = true;
11349                    }
11350                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11351                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11352                }
11353            }
11354        }
11355
11356        if (mPersistentStartingProcesses.size() > 0) {
11357            if (needSep) pw.println();
11358            needSep = true;
11359            printedAnything = true;
11360            pw.println("  Persisent processes that are starting:");
11361            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11362                    "Starting Norm", "Restarting PERS", dumpPackage);
11363        }
11364
11365        if (mRemovedProcesses.size() > 0) {
11366            if (needSep) pw.println();
11367            needSep = true;
11368            printedAnything = true;
11369            pw.println("  Processes that are being removed:");
11370            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11371                    "Removed Norm", "Removed PERS", dumpPackage);
11372        }
11373
11374        if (mProcessesOnHold.size() > 0) {
11375            if (needSep) pw.println();
11376            needSep = true;
11377            printedAnything = true;
11378            pw.println("  Processes that are on old until the system is ready:");
11379            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11380                    "OnHold Norm", "OnHold PERS", dumpPackage);
11381        }
11382
11383        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11384
11385        if (mProcessCrashTimes.getMap().size() > 0) {
11386            boolean printed = false;
11387            long now = SystemClock.uptimeMillis();
11388            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11389            final int NP = pmap.size();
11390            for (int ip=0; ip<NP; ip++) {
11391                String pname = pmap.keyAt(ip);
11392                SparseArray<Long> uids = pmap.valueAt(ip);
11393                final int N = uids.size();
11394                for (int i=0; i<N; i++) {
11395                    int puid = uids.keyAt(i);
11396                    ProcessRecord r = mProcessNames.get(pname, puid);
11397                    if (dumpPackage != null && (r == null
11398                            || !r.pkgList.containsKey(dumpPackage))) {
11399                        continue;
11400                    }
11401                    if (!printed) {
11402                        if (needSep) pw.println();
11403                        needSep = true;
11404                        pw.println("  Time since processes crashed:");
11405                        printed = true;
11406                        printedAnything = true;
11407                    }
11408                    pw.print("    Process "); pw.print(pname);
11409                            pw.print(" uid "); pw.print(puid);
11410                            pw.print(": last crashed ");
11411                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11412                            pw.println(" ago");
11413                }
11414            }
11415        }
11416
11417        if (mBadProcesses.getMap().size() > 0) {
11418            boolean printed = false;
11419            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11420            final int NP = pmap.size();
11421            for (int ip=0; ip<NP; ip++) {
11422                String pname = pmap.keyAt(ip);
11423                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11424                final int N = uids.size();
11425                for (int i=0; i<N; i++) {
11426                    int puid = uids.keyAt(i);
11427                    ProcessRecord r = mProcessNames.get(pname, puid);
11428                    if (dumpPackage != null && (r == null
11429                            || !r.pkgList.containsKey(dumpPackage))) {
11430                        continue;
11431                    }
11432                    if (!printed) {
11433                        if (needSep) pw.println();
11434                        needSep = true;
11435                        pw.println("  Bad processes:");
11436                        printedAnything = true;
11437                    }
11438                    BadProcessInfo info = uids.valueAt(i);
11439                    pw.print("    Bad process "); pw.print(pname);
11440                            pw.print(" uid "); pw.print(puid);
11441                            pw.print(": crashed at time "); pw.println(info.time);
11442                    if (info.shortMsg != null) {
11443                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11444                    }
11445                    if (info.longMsg != null) {
11446                        pw.print("      Long msg: "); pw.println(info.longMsg);
11447                    }
11448                    if (info.stack != null) {
11449                        pw.println("      Stack:");
11450                        int lastPos = 0;
11451                        for (int pos=0; pos<info.stack.length(); pos++) {
11452                            if (info.stack.charAt(pos) == '\n') {
11453                                pw.print("        ");
11454                                pw.write(info.stack, lastPos, pos-lastPos);
11455                                pw.println();
11456                                lastPos = pos+1;
11457                            }
11458                        }
11459                        if (lastPos < info.stack.length()) {
11460                            pw.print("        ");
11461                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11462                            pw.println();
11463                        }
11464                    }
11465                }
11466            }
11467        }
11468
11469        if (dumpPackage == null) {
11470            pw.println();
11471            needSep = false;
11472            pw.println("  mStartedUsers:");
11473            for (int i=0; i<mStartedUsers.size(); i++) {
11474                UserStartedState uss = mStartedUsers.valueAt(i);
11475                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11476                        pw.print(": "); uss.dump("", pw);
11477            }
11478            pw.print("  mStartedUserArray: [");
11479            for (int i=0; i<mStartedUserArray.length; i++) {
11480                if (i > 0) pw.print(", ");
11481                pw.print(mStartedUserArray[i]);
11482            }
11483            pw.println("]");
11484            pw.print("  mUserLru: [");
11485            for (int i=0; i<mUserLru.size(); i++) {
11486                if (i > 0) pw.print(", ");
11487                pw.print(mUserLru.get(i));
11488            }
11489            pw.println("]");
11490            if (dumpAll) {
11491                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11492            }
11493        }
11494        if (mHomeProcess != null && (dumpPackage == null
11495                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11496            if (needSep) {
11497                pw.println();
11498                needSep = false;
11499            }
11500            pw.println("  mHomeProcess: " + mHomeProcess);
11501        }
11502        if (mPreviousProcess != null && (dumpPackage == null
11503                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11504            if (needSep) {
11505                pw.println();
11506                needSep = false;
11507            }
11508            pw.println("  mPreviousProcess: " + mPreviousProcess);
11509        }
11510        if (dumpAll) {
11511            StringBuilder sb = new StringBuilder(128);
11512            sb.append("  mPreviousProcessVisibleTime: ");
11513            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11514            pw.println(sb);
11515        }
11516        if (mHeavyWeightProcess != null && (dumpPackage == null
11517                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11518            if (needSep) {
11519                pw.println();
11520                needSep = false;
11521            }
11522            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11523        }
11524        if (dumpPackage == null) {
11525            pw.println("  mConfiguration: " + mConfiguration);
11526        }
11527        if (dumpAll) {
11528            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11529            if (mCompatModePackages.getPackages().size() > 0) {
11530                boolean printed = false;
11531                for (Map.Entry<String, Integer> entry
11532                        : mCompatModePackages.getPackages().entrySet()) {
11533                    String pkg = entry.getKey();
11534                    int mode = entry.getValue();
11535                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11536                        continue;
11537                    }
11538                    if (!printed) {
11539                        pw.println("  mScreenCompatPackages:");
11540                        printed = true;
11541                    }
11542                    pw.print("    "); pw.print(pkg); pw.print(": ");
11543                            pw.print(mode); pw.println();
11544                }
11545            }
11546        }
11547        if (dumpPackage == null) {
11548            if (mSleeping || mWentToSleep || mLockScreenShown) {
11549                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11550                        + " mLockScreenShown " + mLockScreenShown);
11551            }
11552            if (mShuttingDown || mRunningVoice) {
11553                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11554            }
11555        }
11556        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11557                || mOrigWaitForDebugger) {
11558            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11559                    || dumpPackage.equals(mOrigDebugApp)) {
11560                if (needSep) {
11561                    pw.println();
11562                    needSep = false;
11563                }
11564                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11565                        + " mDebugTransient=" + mDebugTransient
11566                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11567            }
11568        }
11569        if (mOpenGlTraceApp != null) {
11570            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11571                if (needSep) {
11572                    pw.println();
11573                    needSep = false;
11574                }
11575                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11576            }
11577        }
11578        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11579                || mProfileFd != null) {
11580            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11581                if (needSep) {
11582                    pw.println();
11583                    needSep = false;
11584                }
11585                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11586                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11587                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11588                        + mAutoStopProfiler);
11589            }
11590        }
11591        if (dumpPackage == null) {
11592            if (mAlwaysFinishActivities || mController != null) {
11593                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11594                        + " mController=" + mController);
11595            }
11596            if (dumpAll) {
11597                pw.println("  Total persistent processes: " + numPers);
11598                pw.println("  mProcessesReady=" + mProcessesReady
11599                        + " mSystemReady=" + mSystemReady);
11600                pw.println("  mBooting=" + mBooting
11601                        + " mBooted=" + mBooted
11602                        + " mFactoryTest=" + mFactoryTest);
11603                pw.print("  mLastPowerCheckRealtime=");
11604                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11605                        pw.println("");
11606                pw.print("  mLastPowerCheckUptime=");
11607                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11608                        pw.println("");
11609                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11610                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11611                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11612                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11613                        + " (" + mLruProcesses.size() + " total)"
11614                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11615                        + " mNumServiceProcs=" + mNumServiceProcs
11616                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11617                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11618                        + " mLastMemoryLevel" + mLastMemoryLevel
11619                        + " mLastNumProcesses" + mLastNumProcesses);
11620                long now = SystemClock.uptimeMillis();
11621                pw.print("  mLastIdleTime=");
11622                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11623                        pw.print(" mLowRamSinceLastIdle=");
11624                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11625                        pw.println();
11626            }
11627        }
11628
11629        if (!printedAnything) {
11630            pw.println("  (nothing)");
11631        }
11632    }
11633
11634    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11635            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11636        if (mProcessesToGc.size() > 0) {
11637            boolean printed = false;
11638            long now = SystemClock.uptimeMillis();
11639            for (int i=0; i<mProcessesToGc.size(); i++) {
11640                ProcessRecord proc = mProcessesToGc.get(i);
11641                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11642                    continue;
11643                }
11644                if (!printed) {
11645                    if (needSep) pw.println();
11646                    needSep = true;
11647                    pw.println("  Processes that are waiting to GC:");
11648                    printed = true;
11649                }
11650                pw.print("    Process "); pw.println(proc);
11651                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11652                        pw.print(", last gced=");
11653                        pw.print(now-proc.lastRequestedGc);
11654                        pw.print(" ms ago, last lowMem=");
11655                        pw.print(now-proc.lastLowMemory);
11656                        pw.println(" ms ago");
11657
11658            }
11659        }
11660        return needSep;
11661    }
11662
11663    void printOomLevel(PrintWriter pw, String name, int adj) {
11664        pw.print("    ");
11665        if (adj >= 0) {
11666            pw.print(' ');
11667            if (adj < 10) pw.print(' ');
11668        } else {
11669            if (adj > -10) pw.print(' ');
11670        }
11671        pw.print(adj);
11672        pw.print(": ");
11673        pw.print(name);
11674        pw.print(" (");
11675        pw.print(mProcessList.getMemLevel(adj)/1024);
11676        pw.println(" kB)");
11677    }
11678
11679    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11680            int opti, boolean dumpAll) {
11681        boolean needSep = false;
11682
11683        if (mLruProcesses.size() > 0) {
11684            if (needSep) pw.println();
11685            needSep = true;
11686            pw.println("  OOM levels:");
11687            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11688            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11689            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11690            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11691            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11692            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11693            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11694            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11695            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11696            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11697            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11698            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11699            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11700
11701            if (needSep) pw.println();
11702            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11703                    pw.print(" total, non-act at ");
11704                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11705                    pw.print(", non-svc at ");
11706                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11707                    pw.println("):");
11708            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11709            needSep = true;
11710        }
11711
11712        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11713
11714        pw.println();
11715        pw.println("  mHomeProcess: " + mHomeProcess);
11716        pw.println("  mPreviousProcess: " + mPreviousProcess);
11717        if (mHeavyWeightProcess != null) {
11718            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11719        }
11720
11721        return true;
11722    }
11723
11724    /**
11725     * There are three ways to call this:
11726     *  - no provider specified: dump all the providers
11727     *  - a flattened component name that matched an existing provider was specified as the
11728     *    first arg: dump that one provider
11729     *  - the first arg isn't the flattened component name of an existing provider:
11730     *    dump all providers whose component contains the first arg as a substring
11731     */
11732    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11733            int opti, boolean dumpAll) {
11734        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11735    }
11736
11737    static class ItemMatcher {
11738        ArrayList<ComponentName> components;
11739        ArrayList<String> strings;
11740        ArrayList<Integer> objects;
11741        boolean all;
11742
11743        ItemMatcher() {
11744            all = true;
11745        }
11746
11747        void build(String name) {
11748            ComponentName componentName = ComponentName.unflattenFromString(name);
11749            if (componentName != null) {
11750                if (components == null) {
11751                    components = new ArrayList<ComponentName>();
11752                }
11753                components.add(componentName);
11754                all = false;
11755            } else {
11756                int objectId = 0;
11757                // Not a '/' separated full component name; maybe an object ID?
11758                try {
11759                    objectId = Integer.parseInt(name, 16);
11760                    if (objects == null) {
11761                        objects = new ArrayList<Integer>();
11762                    }
11763                    objects.add(objectId);
11764                    all = false;
11765                } catch (RuntimeException e) {
11766                    // Not an integer; just do string match.
11767                    if (strings == null) {
11768                        strings = new ArrayList<String>();
11769                    }
11770                    strings.add(name);
11771                    all = false;
11772                }
11773            }
11774        }
11775
11776        int build(String[] args, int opti) {
11777            for (; opti<args.length; opti++) {
11778                String name = args[opti];
11779                if ("--".equals(name)) {
11780                    return opti+1;
11781                }
11782                build(name);
11783            }
11784            return opti;
11785        }
11786
11787        boolean match(Object object, ComponentName comp) {
11788            if (all) {
11789                return true;
11790            }
11791            if (components != null) {
11792                for (int i=0; i<components.size(); i++) {
11793                    if (components.get(i).equals(comp)) {
11794                        return true;
11795                    }
11796                }
11797            }
11798            if (objects != null) {
11799                for (int i=0; i<objects.size(); i++) {
11800                    if (System.identityHashCode(object) == objects.get(i)) {
11801                        return true;
11802                    }
11803                }
11804            }
11805            if (strings != null) {
11806                String flat = comp.flattenToString();
11807                for (int i=0; i<strings.size(); i++) {
11808                    if (flat.contains(strings.get(i))) {
11809                        return true;
11810                    }
11811                }
11812            }
11813            return false;
11814        }
11815    }
11816
11817    /**
11818     * There are three things that cmd can be:
11819     *  - a flattened component name that matches an existing activity
11820     *  - the cmd arg isn't the flattened component name of an existing activity:
11821     *    dump all activity whose component contains the cmd as a substring
11822     *  - A hex number of the ActivityRecord object instance.
11823     */
11824    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11825            int opti, boolean dumpAll) {
11826        ArrayList<ActivityRecord> activities;
11827
11828        synchronized (this) {
11829            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11830        }
11831
11832        if (activities.size() <= 0) {
11833            return false;
11834        }
11835
11836        String[] newArgs = new String[args.length - opti];
11837        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11838
11839        TaskRecord lastTask = null;
11840        boolean needSep = false;
11841        for (int i=activities.size()-1; i>=0; i--) {
11842            ActivityRecord r = activities.get(i);
11843            if (needSep) {
11844                pw.println();
11845            }
11846            needSep = true;
11847            synchronized (this) {
11848                if (lastTask != r.task) {
11849                    lastTask = r.task;
11850                    pw.print("TASK "); pw.print(lastTask.affinity);
11851                            pw.print(" id="); pw.println(lastTask.taskId);
11852                    if (dumpAll) {
11853                        lastTask.dump(pw, "  ");
11854                    }
11855                }
11856            }
11857            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11858        }
11859        return true;
11860    }
11861
11862    /**
11863     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11864     * there is a thread associated with the activity.
11865     */
11866    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11867            final ActivityRecord r, String[] args, boolean dumpAll) {
11868        String innerPrefix = prefix + "  ";
11869        synchronized (this) {
11870            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11871                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11872                    pw.print(" pid=");
11873                    if (r.app != null) pw.println(r.app.pid);
11874                    else pw.println("(not running)");
11875            if (dumpAll) {
11876                r.dump(pw, innerPrefix);
11877            }
11878        }
11879        if (r.app != null && r.app.thread != null) {
11880            // flush anything that is already in the PrintWriter since the thread is going
11881            // to write to the file descriptor directly
11882            pw.flush();
11883            try {
11884                TransferPipe tp = new TransferPipe();
11885                try {
11886                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11887                            r.appToken, innerPrefix, args);
11888                    tp.go(fd);
11889                } finally {
11890                    tp.kill();
11891                }
11892            } catch (IOException e) {
11893                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11894            } catch (RemoteException e) {
11895                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11896            }
11897        }
11898    }
11899
11900    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11901            int opti, boolean dumpAll, String dumpPackage) {
11902        boolean needSep = false;
11903        boolean onlyHistory = false;
11904        boolean printedAnything = false;
11905
11906        if ("history".equals(dumpPackage)) {
11907            if (opti < args.length && "-s".equals(args[opti])) {
11908                dumpAll = false;
11909            }
11910            onlyHistory = true;
11911            dumpPackage = null;
11912        }
11913
11914        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11915        if (!onlyHistory && dumpAll) {
11916            if (mRegisteredReceivers.size() > 0) {
11917                boolean printed = false;
11918                Iterator it = mRegisteredReceivers.values().iterator();
11919                while (it.hasNext()) {
11920                    ReceiverList r = (ReceiverList)it.next();
11921                    if (dumpPackage != null && (r.app == null ||
11922                            !dumpPackage.equals(r.app.info.packageName))) {
11923                        continue;
11924                    }
11925                    if (!printed) {
11926                        pw.println("  Registered Receivers:");
11927                        needSep = true;
11928                        printed = true;
11929                        printedAnything = true;
11930                    }
11931                    pw.print("  * "); pw.println(r);
11932                    r.dump(pw, "    ");
11933                }
11934            }
11935
11936            if (mReceiverResolver.dump(pw, needSep ?
11937                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11938                    "    ", dumpPackage, false)) {
11939                needSep = true;
11940                printedAnything = true;
11941            }
11942        }
11943
11944        for (BroadcastQueue q : mBroadcastQueues) {
11945            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11946            printedAnything |= needSep;
11947        }
11948
11949        needSep = true;
11950
11951        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11952            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11953                if (needSep) {
11954                    pw.println();
11955                }
11956                needSep = true;
11957                printedAnything = true;
11958                pw.print("  Sticky broadcasts for user ");
11959                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11960                StringBuilder sb = new StringBuilder(128);
11961                for (Map.Entry<String, ArrayList<Intent>> ent
11962                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11963                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11964                    if (dumpAll) {
11965                        pw.println(":");
11966                        ArrayList<Intent> intents = ent.getValue();
11967                        final int N = intents.size();
11968                        for (int i=0; i<N; i++) {
11969                            sb.setLength(0);
11970                            sb.append("    Intent: ");
11971                            intents.get(i).toShortString(sb, false, true, false, false);
11972                            pw.println(sb.toString());
11973                            Bundle bundle = intents.get(i).getExtras();
11974                            if (bundle != null) {
11975                                pw.print("      ");
11976                                pw.println(bundle.toString());
11977                            }
11978                        }
11979                    } else {
11980                        pw.println("");
11981                    }
11982                }
11983            }
11984        }
11985
11986        if (!onlyHistory && dumpAll) {
11987            pw.println();
11988            for (BroadcastQueue queue : mBroadcastQueues) {
11989                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11990                        + queue.mBroadcastsScheduled);
11991            }
11992            pw.println("  mHandler:");
11993            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11994            needSep = true;
11995            printedAnything = true;
11996        }
11997
11998        if (!printedAnything) {
11999            pw.println("  (nothing)");
12000        }
12001    }
12002
12003    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12004            int opti, boolean dumpAll, String dumpPackage) {
12005        boolean needSep;
12006        boolean printedAnything = false;
12007
12008        ItemMatcher matcher = new ItemMatcher();
12009        matcher.build(args, opti);
12010
12011        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12012
12013        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12014        printedAnything |= needSep;
12015
12016        if (mLaunchingProviders.size() > 0) {
12017            boolean printed = false;
12018            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12019                ContentProviderRecord r = mLaunchingProviders.get(i);
12020                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12021                    continue;
12022                }
12023                if (!printed) {
12024                    if (needSep) pw.println();
12025                    needSep = true;
12026                    pw.println("  Launching content providers:");
12027                    printed = true;
12028                    printedAnything = true;
12029                }
12030                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12031                        pw.println(r);
12032            }
12033        }
12034
12035        if (mGrantedUriPermissions.size() > 0) {
12036            boolean printed = false;
12037            int dumpUid = -2;
12038            if (dumpPackage != null) {
12039                try {
12040                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12041                } catch (NameNotFoundException e) {
12042                    dumpUid = -1;
12043                }
12044            }
12045            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12046                int uid = mGrantedUriPermissions.keyAt(i);
12047                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12048                    continue;
12049                }
12050                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12051                if (!printed) {
12052                    if (needSep) pw.println();
12053                    needSep = true;
12054                    pw.println("  Granted Uri Permissions:");
12055                    printed = true;
12056                    printedAnything = true;
12057                }
12058                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12059                for (UriPermission perm : perms.values()) {
12060                    pw.print("    "); pw.println(perm);
12061                    if (dumpAll) {
12062                        perm.dump(pw, "      ");
12063                    }
12064                }
12065            }
12066        }
12067
12068        if (!printedAnything) {
12069            pw.println("  (nothing)");
12070        }
12071    }
12072
12073    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12074            int opti, boolean dumpAll, String dumpPackage) {
12075        boolean printed = false;
12076
12077        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12078
12079        if (mIntentSenderRecords.size() > 0) {
12080            Iterator<WeakReference<PendingIntentRecord>> it
12081                    = mIntentSenderRecords.values().iterator();
12082            while (it.hasNext()) {
12083                WeakReference<PendingIntentRecord> ref = it.next();
12084                PendingIntentRecord rec = ref != null ? ref.get(): null;
12085                if (dumpPackage != null && (rec == null
12086                        || !dumpPackage.equals(rec.key.packageName))) {
12087                    continue;
12088                }
12089                printed = true;
12090                if (rec != null) {
12091                    pw.print("  * "); pw.println(rec);
12092                    if (dumpAll) {
12093                        rec.dump(pw, "    ");
12094                    }
12095                } else {
12096                    pw.print("  * "); pw.println(ref);
12097                }
12098            }
12099        }
12100
12101        if (!printed) {
12102            pw.println("  (nothing)");
12103        }
12104    }
12105
12106    private static final int dumpProcessList(PrintWriter pw,
12107            ActivityManagerService service, List list,
12108            String prefix, String normalLabel, String persistentLabel,
12109            String dumpPackage) {
12110        int numPers = 0;
12111        final int N = list.size()-1;
12112        for (int i=N; i>=0; i--) {
12113            ProcessRecord r = (ProcessRecord)list.get(i);
12114            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12115                continue;
12116            }
12117            pw.println(String.format("%s%s #%2d: %s",
12118                    prefix, (r.persistent ? persistentLabel : normalLabel),
12119                    i, r.toString()));
12120            if (r.persistent) {
12121                numPers++;
12122            }
12123        }
12124        return numPers;
12125    }
12126
12127    private static final boolean dumpProcessOomList(PrintWriter pw,
12128            ActivityManagerService service, List<ProcessRecord> origList,
12129            String prefix, String normalLabel, String persistentLabel,
12130            boolean inclDetails, String dumpPackage) {
12131
12132        ArrayList<Pair<ProcessRecord, Integer>> list
12133                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12134        for (int i=0; i<origList.size(); i++) {
12135            ProcessRecord r = origList.get(i);
12136            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12137                continue;
12138            }
12139            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12140        }
12141
12142        if (list.size() <= 0) {
12143            return false;
12144        }
12145
12146        Comparator<Pair<ProcessRecord, Integer>> comparator
12147                = new Comparator<Pair<ProcessRecord, Integer>>() {
12148            @Override
12149            public int compare(Pair<ProcessRecord, Integer> object1,
12150                    Pair<ProcessRecord, Integer> object2) {
12151                if (object1.first.setAdj != object2.first.setAdj) {
12152                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12153                }
12154                if (object1.second.intValue() != object2.second.intValue()) {
12155                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12156                }
12157                return 0;
12158            }
12159        };
12160
12161        Collections.sort(list, comparator);
12162
12163        final long curRealtime = SystemClock.elapsedRealtime();
12164        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12165        final long curUptime = SystemClock.uptimeMillis();
12166        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12167
12168        for (int i=list.size()-1; i>=0; i--) {
12169            ProcessRecord r = list.get(i).first;
12170            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12171            char schedGroup;
12172            switch (r.setSchedGroup) {
12173                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12174                    schedGroup = 'B';
12175                    break;
12176                case Process.THREAD_GROUP_DEFAULT:
12177                    schedGroup = 'F';
12178                    break;
12179                default:
12180                    schedGroup = '?';
12181                    break;
12182            }
12183            char foreground;
12184            if (r.foregroundActivities) {
12185                foreground = 'A';
12186            } else if (r.foregroundServices) {
12187                foreground = 'S';
12188            } else {
12189                foreground = ' ';
12190            }
12191            String procState = ProcessList.makeProcStateString(r.curProcState);
12192            pw.print(prefix);
12193            pw.print(r.persistent ? persistentLabel : normalLabel);
12194            pw.print(" #");
12195            int num = (origList.size()-1)-list.get(i).second;
12196            if (num < 10) pw.print(' ');
12197            pw.print(num);
12198            pw.print(": ");
12199            pw.print(oomAdj);
12200            pw.print(' ');
12201            pw.print(schedGroup);
12202            pw.print('/');
12203            pw.print(foreground);
12204            pw.print('/');
12205            pw.print(procState);
12206            pw.print(" trm:");
12207            if (r.trimMemoryLevel < 10) pw.print(' ');
12208            pw.print(r.trimMemoryLevel);
12209            pw.print(' ');
12210            pw.print(r.toShortString());
12211            pw.print(" (");
12212            pw.print(r.adjType);
12213            pw.println(')');
12214            if (r.adjSource != null || r.adjTarget != null) {
12215                pw.print(prefix);
12216                pw.print("    ");
12217                if (r.adjTarget instanceof ComponentName) {
12218                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12219                } else if (r.adjTarget != null) {
12220                    pw.print(r.adjTarget.toString());
12221                } else {
12222                    pw.print("{null}");
12223                }
12224                pw.print("<=");
12225                if (r.adjSource instanceof ProcessRecord) {
12226                    pw.print("Proc{");
12227                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12228                    pw.println("}");
12229                } else if (r.adjSource != null) {
12230                    pw.println(r.adjSource.toString());
12231                } else {
12232                    pw.println("{null}");
12233                }
12234            }
12235            if (inclDetails) {
12236                pw.print(prefix);
12237                pw.print("    ");
12238                pw.print("oom: max="); pw.print(r.maxAdj);
12239                pw.print(" curRaw="); pw.print(r.curRawAdj);
12240                pw.print(" setRaw="); pw.print(r.setRawAdj);
12241                pw.print(" cur="); pw.print(r.curAdj);
12242                pw.print(" set="); pw.println(r.setAdj);
12243                pw.print(prefix);
12244                pw.print("    ");
12245                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12246                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12247                pw.print(" lastPss="); pw.print(r.lastPss);
12248                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12249                pw.print(prefix);
12250                pw.print("    ");
12251                pw.print("keeping="); pw.print(r.keeping);
12252                pw.print(" cached="); pw.print(r.cached);
12253                pw.print(" empty="); pw.print(r.empty);
12254                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12255
12256                if (!r.keeping) {
12257                    if (r.lastWakeTime != 0) {
12258                        long wtime;
12259                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12260                        synchronized (stats) {
12261                            wtime = stats.getProcessWakeTime(r.info.uid,
12262                                    r.pid, curRealtime);
12263                        }
12264                        long timeUsed = wtime - r.lastWakeTime;
12265                        pw.print(prefix);
12266                        pw.print("    ");
12267                        pw.print("keep awake over ");
12268                        TimeUtils.formatDuration(realtimeSince, pw);
12269                        pw.print(" used ");
12270                        TimeUtils.formatDuration(timeUsed, pw);
12271                        pw.print(" (");
12272                        pw.print((timeUsed*100)/realtimeSince);
12273                        pw.println("%)");
12274                    }
12275                    if (r.lastCpuTime != 0) {
12276                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12277                        pw.print(prefix);
12278                        pw.print("    ");
12279                        pw.print("run cpu over ");
12280                        TimeUtils.formatDuration(uptimeSince, pw);
12281                        pw.print(" used ");
12282                        TimeUtils.formatDuration(timeUsed, pw);
12283                        pw.print(" (");
12284                        pw.print((timeUsed*100)/uptimeSince);
12285                        pw.println("%)");
12286                    }
12287                }
12288            }
12289        }
12290        return true;
12291    }
12292
12293    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12294        ArrayList<ProcessRecord> procs;
12295        synchronized (this) {
12296            if (args != null && args.length > start
12297                    && args[start].charAt(0) != '-') {
12298                procs = new ArrayList<ProcessRecord>();
12299                int pid = -1;
12300                try {
12301                    pid = Integer.parseInt(args[start]);
12302                } catch (NumberFormatException e) {
12303                }
12304                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12305                    ProcessRecord proc = mLruProcesses.get(i);
12306                    if (proc.pid == pid) {
12307                        procs.add(proc);
12308                    } else if (proc.processName.equals(args[start])) {
12309                        procs.add(proc);
12310                    }
12311                }
12312                if (procs.size() <= 0) {
12313                    return null;
12314                }
12315            } else {
12316                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12317            }
12318        }
12319        return procs;
12320    }
12321
12322    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12323            PrintWriter pw, String[] args) {
12324        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12325        if (procs == null) {
12326            pw.println("No process found for: " + args[0]);
12327            return;
12328        }
12329
12330        long uptime = SystemClock.uptimeMillis();
12331        long realtime = SystemClock.elapsedRealtime();
12332        pw.println("Applications Graphics Acceleration Info:");
12333        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12334
12335        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12336            ProcessRecord r = procs.get(i);
12337            if (r.thread != null) {
12338                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12339                pw.flush();
12340                try {
12341                    TransferPipe tp = new TransferPipe();
12342                    try {
12343                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12344                        tp.go(fd);
12345                    } finally {
12346                        tp.kill();
12347                    }
12348                } catch (IOException e) {
12349                    pw.println("Failure while dumping the app: " + r);
12350                    pw.flush();
12351                } catch (RemoteException e) {
12352                    pw.println("Got a RemoteException while dumping the app " + r);
12353                    pw.flush();
12354                }
12355            }
12356        }
12357    }
12358
12359    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12360        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12361        if (procs == null) {
12362            pw.println("No process found for: " + args[0]);
12363            return;
12364        }
12365
12366        pw.println("Applications Database Info:");
12367
12368        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12369            ProcessRecord r = procs.get(i);
12370            if (r.thread != null) {
12371                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12372                pw.flush();
12373                try {
12374                    TransferPipe tp = new TransferPipe();
12375                    try {
12376                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12377                        tp.go(fd);
12378                    } finally {
12379                        tp.kill();
12380                    }
12381                } catch (IOException e) {
12382                    pw.println("Failure while dumping the app: " + r);
12383                    pw.flush();
12384                } catch (RemoteException e) {
12385                    pw.println("Got a RemoteException while dumping the app " + r);
12386                    pw.flush();
12387                }
12388            }
12389        }
12390    }
12391
12392    final static class MemItem {
12393        final boolean isProc;
12394        final String label;
12395        final String shortLabel;
12396        final long pss;
12397        final int id;
12398        final boolean hasActivities;
12399        ArrayList<MemItem> subitems;
12400
12401        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12402                boolean _hasActivities) {
12403            isProc = true;
12404            label = _label;
12405            shortLabel = _shortLabel;
12406            pss = _pss;
12407            id = _id;
12408            hasActivities = _hasActivities;
12409        }
12410
12411        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12412            isProc = false;
12413            label = _label;
12414            shortLabel = _shortLabel;
12415            pss = _pss;
12416            id = _id;
12417            hasActivities = false;
12418        }
12419    }
12420
12421    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12422            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12423        if (sort && !isCompact) {
12424            Collections.sort(items, new Comparator<MemItem>() {
12425                @Override
12426                public int compare(MemItem lhs, MemItem rhs) {
12427                    if (lhs.pss < rhs.pss) {
12428                        return 1;
12429                    } else if (lhs.pss > rhs.pss) {
12430                        return -1;
12431                    }
12432                    return 0;
12433                }
12434            });
12435        }
12436
12437        for (int i=0; i<items.size(); i++) {
12438            MemItem mi = items.get(i);
12439            if (!isCompact) {
12440                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12441            } else if (mi.isProc) {
12442                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12443                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12444                pw.println(mi.hasActivities ? ",a" : ",e");
12445            } else {
12446                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12447                pw.println(mi.pss);
12448            }
12449            if (mi.subitems != null) {
12450                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12451                        true, isCompact);
12452            }
12453        }
12454    }
12455
12456    // These are in KB.
12457    static final long[] DUMP_MEM_BUCKETS = new long[] {
12458        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12459        120*1024, 160*1024, 200*1024,
12460        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12461        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12462    };
12463
12464    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12465            boolean stackLike) {
12466        int start = label.lastIndexOf('.');
12467        if (start >= 0) start++;
12468        else start = 0;
12469        int end = label.length();
12470        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12471            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12472                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12473                out.append(bucket);
12474                out.append(stackLike ? "MB." : "MB ");
12475                out.append(label, start, end);
12476                return;
12477            }
12478        }
12479        out.append(memKB/1024);
12480        out.append(stackLike ? "MB." : "MB ");
12481        out.append(label, start, end);
12482    }
12483
12484    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12485            ProcessList.NATIVE_ADJ,
12486            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12487            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12488            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12489            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12490            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12491    };
12492    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12493            "Native",
12494            "System", "Persistent", "Foreground",
12495            "Visible", "Perceptible",
12496            "Heavy Weight", "Backup",
12497            "A Services", "Home",
12498            "Previous", "B Services", "Cached"
12499    };
12500    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12501            "native",
12502            "sys", "pers", "fore",
12503            "vis", "percept",
12504            "heavy", "backup",
12505            "servicea", "home",
12506            "prev", "serviceb", "cached"
12507    };
12508
12509    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12510            long realtime, boolean isCheckinRequest, boolean isCompact) {
12511        if (isCheckinRequest || isCompact) {
12512            // short checkin version
12513            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12514        } else {
12515            pw.println("Applications Memory Usage (kB):");
12516            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12517        }
12518    }
12519
12520    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12521            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12522        boolean dumpDetails = false;
12523        boolean dumpFullDetails = false;
12524        boolean dumpDalvik = false;
12525        boolean oomOnly = false;
12526        boolean isCompact = false;
12527        boolean localOnly = false;
12528
12529        int opti = 0;
12530        while (opti < args.length) {
12531            String opt = args[opti];
12532            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12533                break;
12534            }
12535            opti++;
12536            if ("-a".equals(opt)) {
12537                dumpDetails = true;
12538                dumpFullDetails = true;
12539                dumpDalvik = true;
12540            } else if ("-d".equals(opt)) {
12541                dumpDalvik = true;
12542            } else if ("-c".equals(opt)) {
12543                isCompact = true;
12544            } else if ("--oom".equals(opt)) {
12545                oomOnly = true;
12546            } else if ("--local".equals(opt)) {
12547                localOnly = true;
12548            } else if ("-h".equals(opt)) {
12549                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12550                pw.println("  -a: include all available information for each process.");
12551                pw.println("  -d: include dalvik details when dumping process details.");
12552                pw.println("  -c: dump in a compact machine-parseable representation.");
12553                pw.println("  --oom: only show processes organized by oom adj.");
12554                pw.println("  --local: only collect details locally, don't call process.");
12555                pw.println("If [process] is specified it can be the name or ");
12556                pw.println("pid of a specific process to dump.");
12557                return;
12558            } else {
12559                pw.println("Unknown argument: " + opt + "; use -h for help");
12560            }
12561        }
12562
12563        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12564        long uptime = SystemClock.uptimeMillis();
12565        long realtime = SystemClock.elapsedRealtime();
12566        final long[] tmpLong = new long[1];
12567
12568        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12569        if (procs == null) {
12570            // No Java processes.  Maybe they want to print a native process.
12571            if (args != null && args.length > opti
12572                    && args[opti].charAt(0) != '-') {
12573                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12574                        = new ArrayList<ProcessCpuTracker.Stats>();
12575                updateCpuStatsNow();
12576                int findPid = -1;
12577                try {
12578                    findPid = Integer.parseInt(args[opti]);
12579                } catch (NumberFormatException e) {
12580                }
12581                synchronized (mProcessCpuThread) {
12582                    final int N = mProcessCpuTracker.countStats();
12583                    for (int i=0; i<N; i++) {
12584                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12585                        if (st.pid == findPid || (st.baseName != null
12586                                && st.baseName.equals(args[opti]))) {
12587                            nativeProcs.add(st);
12588                        }
12589                    }
12590                }
12591                if (nativeProcs.size() > 0) {
12592                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12593                            isCompact);
12594                    Debug.MemoryInfo mi = null;
12595                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12596                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12597                        final int pid = r.pid;
12598                        if (!isCheckinRequest && dumpDetails) {
12599                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12600                        }
12601                        if (mi == null) {
12602                            mi = new Debug.MemoryInfo();
12603                        }
12604                        if (dumpDetails || (!brief && !oomOnly)) {
12605                            Debug.getMemoryInfo(pid, mi);
12606                        } else {
12607                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12608                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12609                        }
12610                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12611                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12612                        if (isCheckinRequest) {
12613                            pw.println();
12614                        }
12615                    }
12616                    return;
12617                }
12618            }
12619            pw.println("No process found for: " + args[opti]);
12620            return;
12621        }
12622
12623        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12624            dumpDetails = true;
12625        }
12626
12627        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12628
12629        String[] innerArgs = new String[args.length-opti];
12630        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12631
12632        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12633        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12634        long nativePss=0, dalvikPss=0, otherPss=0;
12635        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12636
12637        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12638        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12639                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12640
12641        long totalPss = 0;
12642        long cachedPss = 0;
12643
12644        Debug.MemoryInfo mi = null;
12645        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12646            final ProcessRecord r = procs.get(i);
12647            final IApplicationThread thread;
12648            final int pid;
12649            final int oomAdj;
12650            final boolean hasActivities;
12651            synchronized (this) {
12652                thread = r.thread;
12653                pid = r.pid;
12654                oomAdj = r.getSetAdjWithServices();
12655                hasActivities = r.activities.size() > 0;
12656            }
12657            if (thread != null) {
12658                if (!isCheckinRequest && dumpDetails) {
12659                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12660                }
12661                if (mi == null) {
12662                    mi = new Debug.MemoryInfo();
12663                }
12664                if (dumpDetails || (!brief && !oomOnly)) {
12665                    Debug.getMemoryInfo(pid, mi);
12666                } else {
12667                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12668                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12669                }
12670                if (dumpDetails) {
12671                    if (localOnly) {
12672                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12673                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12674                        if (isCheckinRequest) {
12675                            pw.println();
12676                        }
12677                    } else {
12678                        try {
12679                            pw.flush();
12680                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12681                                    dumpDalvik, innerArgs);
12682                        } catch (RemoteException e) {
12683                            if (!isCheckinRequest) {
12684                                pw.println("Got RemoteException!");
12685                                pw.flush();
12686                            }
12687                        }
12688                    }
12689                }
12690
12691                final long myTotalPss = mi.getTotalPss();
12692                final long myTotalUss = mi.getTotalUss();
12693
12694                synchronized (this) {
12695                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12696                        // Record this for posterity if the process has been stable.
12697                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12698                    }
12699                }
12700
12701                if (!isCheckinRequest && mi != null) {
12702                    totalPss += myTotalPss;
12703                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12704                            (hasActivities ? " / activities)" : ")"),
12705                            r.processName, myTotalPss, pid, hasActivities);
12706                    procMems.add(pssItem);
12707                    procMemsMap.put(pid, pssItem);
12708
12709                    nativePss += mi.nativePss;
12710                    dalvikPss += mi.dalvikPss;
12711                    otherPss += mi.otherPss;
12712                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12713                        long mem = mi.getOtherPss(j);
12714                        miscPss[j] += mem;
12715                        otherPss -= mem;
12716                    }
12717
12718                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12719                        cachedPss += myTotalPss;
12720                    }
12721
12722                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12723                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12724                                || oomIndex == (oomPss.length-1)) {
12725                            oomPss[oomIndex] += myTotalPss;
12726                            if (oomProcs[oomIndex] == null) {
12727                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12728                            }
12729                            oomProcs[oomIndex].add(pssItem);
12730                            break;
12731                        }
12732                    }
12733                }
12734            }
12735        }
12736
12737        long nativeProcTotalPss = 0;
12738
12739        if (!isCheckinRequest && procs.size() > 1) {
12740            // If we are showing aggregations, also look for native processes to
12741            // include so that our aggregations are more accurate.
12742            updateCpuStatsNow();
12743            synchronized (mProcessCpuThread) {
12744                final int N = mProcessCpuTracker.countStats();
12745                for (int i=0; i<N; i++) {
12746                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12747                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12748                        if (mi == null) {
12749                            mi = new Debug.MemoryInfo();
12750                        }
12751                        if (!brief && !oomOnly) {
12752                            Debug.getMemoryInfo(st.pid, mi);
12753                        } else {
12754                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12755                            mi.nativePrivateDirty = (int)tmpLong[0];
12756                        }
12757
12758                        final long myTotalPss = mi.getTotalPss();
12759                        totalPss += myTotalPss;
12760                        nativeProcTotalPss += myTotalPss;
12761
12762                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12763                                st.name, myTotalPss, st.pid, false);
12764                        procMems.add(pssItem);
12765
12766                        nativePss += mi.nativePss;
12767                        dalvikPss += mi.dalvikPss;
12768                        otherPss += mi.otherPss;
12769                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12770                            long mem = mi.getOtherPss(j);
12771                            miscPss[j] += mem;
12772                            otherPss -= mem;
12773                        }
12774                        oomPss[0] += myTotalPss;
12775                        if (oomProcs[0] == null) {
12776                            oomProcs[0] = new ArrayList<MemItem>();
12777                        }
12778                        oomProcs[0].add(pssItem);
12779                    }
12780                }
12781            }
12782
12783            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12784
12785            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12786            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12787            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12788            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12789                String label = Debug.MemoryInfo.getOtherLabel(j);
12790                catMems.add(new MemItem(label, label, miscPss[j], j));
12791            }
12792
12793            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12794            for (int j=0; j<oomPss.length; j++) {
12795                if (oomPss[j] != 0) {
12796                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12797                            : DUMP_MEM_OOM_LABEL[j];
12798                    MemItem item = new MemItem(label, label, oomPss[j],
12799                            DUMP_MEM_OOM_ADJ[j]);
12800                    item.subitems = oomProcs[j];
12801                    oomMems.add(item);
12802                }
12803            }
12804
12805            if (!brief && !oomOnly && !isCompact) {
12806                pw.println();
12807                pw.println("Total PSS by process:");
12808                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12809                pw.println();
12810            }
12811            if (!isCompact) {
12812                pw.println("Total PSS by OOM adjustment:");
12813            }
12814            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12815            if (!brief && !oomOnly) {
12816                PrintWriter out = categoryPw != null ? categoryPw : pw;
12817                if (!isCompact) {
12818                    out.println();
12819                    out.println("Total PSS by category:");
12820                }
12821                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12822            }
12823            if (!isCompact) {
12824                pw.println();
12825            }
12826            MemInfoReader memInfo = new MemInfoReader();
12827            memInfo.readMemInfo();
12828            if (nativeProcTotalPss > 0) {
12829                synchronized (this) {
12830                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12831                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12832                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12833                            nativeProcTotalPss);
12834                }
12835            }
12836            if (!brief) {
12837                if (!isCompact) {
12838                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12839                    pw.print(" kB (status ");
12840                    switch (mLastMemoryLevel) {
12841                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12842                            pw.println("normal)");
12843                            break;
12844                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12845                            pw.println("moderate)");
12846                            break;
12847                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12848                            pw.println("low)");
12849                            break;
12850                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12851                            pw.println("critical)");
12852                            break;
12853                        default:
12854                            pw.print(mLastMemoryLevel);
12855                            pw.println(")");
12856                            break;
12857                    }
12858                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12859                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12860                            pw.print(cachedPss); pw.print(" cached pss + ");
12861                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12862                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12863                } else {
12864                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12865                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12866                            + memInfo.getFreeSizeKb()); pw.print(",");
12867                    pw.println(totalPss - cachedPss);
12868                }
12869            }
12870            if (!isCompact) {
12871                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12872                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12873                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12874                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12875                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12876                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12877                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12878                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12879                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12880                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12881                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12882            }
12883            if (!brief) {
12884                if (memInfo.getZramTotalSizeKb() != 0) {
12885                    if (!isCompact) {
12886                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12887                                pw.print(" kB physical used for ");
12888                                pw.print(memInfo.getSwapTotalSizeKb()
12889                                        - memInfo.getSwapFreeSizeKb());
12890                                pw.print(" kB in swap (");
12891                                pw.print(memInfo.getSwapTotalSizeKb());
12892                                pw.println(" kB total swap)");
12893                    } else {
12894                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12895                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12896                                pw.println(memInfo.getSwapFreeSizeKb());
12897                    }
12898                }
12899                final int[] SINGLE_LONG_FORMAT = new int[] {
12900                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12901                };
12902                long[] longOut = new long[1];
12903                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12904                        SINGLE_LONG_FORMAT, null, longOut, null);
12905                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12906                longOut[0] = 0;
12907                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12908                        SINGLE_LONG_FORMAT, null, longOut, null);
12909                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12910                longOut[0] = 0;
12911                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12912                        SINGLE_LONG_FORMAT, null, longOut, null);
12913                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12914                longOut[0] = 0;
12915                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12916                        SINGLE_LONG_FORMAT, null, longOut, null);
12917                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12918                if (!isCompact) {
12919                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12920                        pw.print("      KSM: "); pw.print(sharing);
12921                                pw.print(" kB saved from shared ");
12922                                pw.print(shared); pw.println(" kB");
12923                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12924                                pw.print(voltile); pw.println(" kB volatile");
12925                    }
12926                    pw.print("   Tuning: ");
12927                    pw.print(ActivityManager.staticGetMemoryClass());
12928                    pw.print(" (large ");
12929                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12930                    pw.print("), oom ");
12931                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12932                    pw.print(" kB");
12933                    pw.print(", restore limit ");
12934                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12935                    pw.print(" kB");
12936                    if (ActivityManager.isLowRamDeviceStatic()) {
12937                        pw.print(" (low-ram)");
12938                    }
12939                    if (ActivityManager.isHighEndGfx()) {
12940                        pw.print(" (high-end-gfx)");
12941                    }
12942                    pw.println();
12943                } else {
12944                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12945                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12946                    pw.println(voltile);
12947                    pw.print("tuning,");
12948                    pw.print(ActivityManager.staticGetMemoryClass());
12949                    pw.print(',');
12950                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12951                    pw.print(',');
12952                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12953                    if (ActivityManager.isLowRamDeviceStatic()) {
12954                        pw.print(",low-ram");
12955                    }
12956                    if (ActivityManager.isHighEndGfx()) {
12957                        pw.print(",high-end-gfx");
12958                    }
12959                    pw.println();
12960                }
12961            }
12962        }
12963    }
12964
12965    /**
12966     * Searches array of arguments for the specified string
12967     * @param args array of argument strings
12968     * @param value value to search for
12969     * @return true if the value is contained in the array
12970     */
12971    private static boolean scanArgs(String[] args, String value) {
12972        if (args != null) {
12973            for (String arg : args) {
12974                if (value.equals(arg)) {
12975                    return true;
12976                }
12977            }
12978        }
12979        return false;
12980    }
12981
12982    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12983            ContentProviderRecord cpr, boolean always) {
12984        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12985
12986        if (!inLaunching || always) {
12987            synchronized (cpr) {
12988                cpr.launchingApp = null;
12989                cpr.notifyAll();
12990            }
12991            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12992            String names[] = cpr.info.authority.split(";");
12993            for (int j = 0; j < names.length; j++) {
12994                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12995            }
12996        }
12997
12998        for (int i=0; i<cpr.connections.size(); i++) {
12999            ContentProviderConnection conn = cpr.connections.get(i);
13000            if (conn.waiting) {
13001                // If this connection is waiting for the provider, then we don't
13002                // need to mess with its process unless we are always removing
13003                // or for some reason the provider is not currently launching.
13004                if (inLaunching && !always) {
13005                    continue;
13006                }
13007            }
13008            ProcessRecord capp = conn.client;
13009            conn.dead = true;
13010            if (conn.stableCount > 0) {
13011                if (!capp.persistent && capp.thread != null
13012                        && capp.pid != 0
13013                        && capp.pid != MY_PID) {
13014                    killUnneededProcessLocked(capp, "depends on provider "
13015                            + cpr.name.flattenToShortString()
13016                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13017                }
13018            } else if (capp.thread != null && conn.provider.provider != null) {
13019                try {
13020                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13021                } catch (RemoteException e) {
13022                }
13023                // In the protocol here, we don't expect the client to correctly
13024                // clean up this connection, we'll just remove it.
13025                cpr.connections.remove(i);
13026                conn.client.conProviders.remove(conn);
13027            }
13028        }
13029
13030        if (inLaunching && always) {
13031            mLaunchingProviders.remove(cpr);
13032        }
13033        return inLaunching;
13034    }
13035
13036    /**
13037     * Main code for cleaning up a process when it has gone away.  This is
13038     * called both as a result of the process dying, or directly when stopping
13039     * a process when running in single process mode.
13040     */
13041    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13042            boolean restarting, boolean allowRestart, int index) {
13043        if (index >= 0) {
13044            removeLruProcessLocked(app);
13045            ProcessList.remove(app.pid);
13046        }
13047
13048        mProcessesToGc.remove(app);
13049        mPendingPssProcesses.remove(app);
13050
13051        // Dismiss any open dialogs.
13052        if (app.crashDialog != null && !app.forceCrashReport) {
13053            app.crashDialog.dismiss();
13054            app.crashDialog = null;
13055        }
13056        if (app.anrDialog != null) {
13057            app.anrDialog.dismiss();
13058            app.anrDialog = null;
13059        }
13060        if (app.waitDialog != null) {
13061            app.waitDialog.dismiss();
13062            app.waitDialog = null;
13063        }
13064
13065        app.crashing = false;
13066        app.notResponding = false;
13067
13068        app.resetPackageList(mProcessStats);
13069        app.unlinkDeathRecipient();
13070        app.makeInactive(mProcessStats);
13071        app.forcingToForeground = null;
13072        updateProcessForegroundLocked(app, false, false);
13073        app.foregroundActivities = false;
13074        app.hasShownUi = false;
13075        app.treatLikeActivity = false;
13076        app.hasAboveClient = false;
13077        app.hasClientActivities = false;
13078
13079        mServices.killServicesLocked(app, allowRestart);
13080
13081        boolean restart = false;
13082
13083        // Remove published content providers.
13084        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13085            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13086            final boolean always = app.bad || !allowRestart;
13087            if (removeDyingProviderLocked(app, cpr, always) || always) {
13088                // We left the provider in the launching list, need to
13089                // restart it.
13090                restart = true;
13091            }
13092
13093            cpr.provider = null;
13094            cpr.proc = null;
13095        }
13096        app.pubProviders.clear();
13097
13098        // Take care of any launching providers waiting for this process.
13099        if (checkAppInLaunchingProvidersLocked(app, false)) {
13100            restart = true;
13101        }
13102
13103        // Unregister from connected content providers.
13104        if (!app.conProviders.isEmpty()) {
13105            for (int i=0; i<app.conProviders.size(); i++) {
13106                ContentProviderConnection conn = app.conProviders.get(i);
13107                conn.provider.connections.remove(conn);
13108            }
13109            app.conProviders.clear();
13110        }
13111
13112        // At this point there may be remaining entries in mLaunchingProviders
13113        // where we were the only one waiting, so they are no longer of use.
13114        // Look for these and clean up if found.
13115        // XXX Commented out for now.  Trying to figure out a way to reproduce
13116        // the actual situation to identify what is actually going on.
13117        if (false) {
13118            for (int i=0; i<mLaunchingProviders.size(); i++) {
13119                ContentProviderRecord cpr = (ContentProviderRecord)
13120                        mLaunchingProviders.get(i);
13121                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13122                    synchronized (cpr) {
13123                        cpr.launchingApp = null;
13124                        cpr.notifyAll();
13125                    }
13126                }
13127            }
13128        }
13129
13130        skipCurrentReceiverLocked(app);
13131
13132        // Unregister any receivers.
13133        for (int i=app.receivers.size()-1; i>=0; i--) {
13134            removeReceiverLocked(app.receivers.valueAt(i));
13135        }
13136        app.receivers.clear();
13137
13138        // If the app is undergoing backup, tell the backup manager about it
13139        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13140            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13141                    + mBackupTarget.appInfo + " died during backup");
13142            try {
13143                IBackupManager bm = IBackupManager.Stub.asInterface(
13144                        ServiceManager.getService(Context.BACKUP_SERVICE));
13145                bm.agentDisconnected(app.info.packageName);
13146            } catch (RemoteException e) {
13147                // can't happen; backup manager is local
13148            }
13149        }
13150
13151        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13152            ProcessChangeItem item = mPendingProcessChanges.get(i);
13153            if (item.pid == app.pid) {
13154                mPendingProcessChanges.remove(i);
13155                mAvailProcessChanges.add(item);
13156            }
13157        }
13158        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13159
13160        // If the caller is restarting this app, then leave it in its
13161        // current lists and let the caller take care of it.
13162        if (restarting) {
13163            return;
13164        }
13165
13166        if (!app.persistent || app.isolated) {
13167            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13168                    "Removing non-persistent process during cleanup: " + app);
13169            mProcessNames.remove(app.processName, app.uid);
13170            mIsolatedProcesses.remove(app.uid);
13171            if (mHeavyWeightProcess == app) {
13172                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13173                        mHeavyWeightProcess.userId, 0));
13174                mHeavyWeightProcess = null;
13175            }
13176        } else if (!app.removed) {
13177            // This app is persistent, so we need to keep its record around.
13178            // If it is not already on the pending app list, add it there
13179            // and start a new process for it.
13180            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13181                mPersistentStartingProcesses.add(app);
13182                restart = true;
13183            }
13184        }
13185        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13186                "Clean-up removing on hold: " + app);
13187        mProcessesOnHold.remove(app);
13188
13189        if (app == mHomeProcess) {
13190            mHomeProcess = null;
13191        }
13192        if (app == mPreviousProcess) {
13193            mPreviousProcess = null;
13194        }
13195
13196        if (restart && !app.isolated) {
13197            // We have components that still need to be running in the
13198            // process, so re-launch it.
13199            mProcessNames.put(app.processName, app.uid, app);
13200            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13201        } else if (app.pid > 0 && app.pid != MY_PID) {
13202            // Goodbye!
13203            boolean removed;
13204            synchronized (mPidsSelfLocked) {
13205                mPidsSelfLocked.remove(app.pid);
13206                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13207            }
13208            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13209                    app.processName, app.info.uid);
13210            if (app.isolated) {
13211                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13212            }
13213            app.setPid(0);
13214        }
13215    }
13216
13217    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13218        // Look through the content providers we are waiting to have launched,
13219        // and if any run in this process then either schedule a restart of
13220        // the process or kill the client waiting for it if this process has
13221        // gone bad.
13222        int NL = mLaunchingProviders.size();
13223        boolean restart = false;
13224        for (int i=0; i<NL; i++) {
13225            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13226            if (cpr.launchingApp == app) {
13227                if (!alwaysBad && !app.bad) {
13228                    restart = true;
13229                } else {
13230                    removeDyingProviderLocked(app, cpr, true);
13231                    // cpr should have been removed from mLaunchingProviders
13232                    NL = mLaunchingProviders.size();
13233                    i--;
13234                }
13235            }
13236        }
13237        return restart;
13238    }
13239
13240    // =========================================================
13241    // SERVICES
13242    // =========================================================
13243
13244    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13245            int flags) {
13246        enforceNotIsolatedCaller("getServices");
13247        synchronized (this) {
13248            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13249        }
13250    }
13251
13252    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13253        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13254        synchronized (this) {
13255            return mServices.getRunningServiceControlPanelLocked(name);
13256        }
13257    }
13258
13259    public ComponentName startService(IApplicationThread caller, Intent service,
13260            String resolvedType, int userId) {
13261        enforceNotIsolatedCaller("startService");
13262        // Refuse possible leaked file descriptors
13263        if (service != null && service.hasFileDescriptors() == true) {
13264            throw new IllegalArgumentException("File descriptors passed in Intent");
13265        }
13266
13267        if (DEBUG_SERVICE)
13268            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13269        synchronized(this) {
13270            final int callingPid = Binder.getCallingPid();
13271            final int callingUid = Binder.getCallingUid();
13272            final long origId = Binder.clearCallingIdentity();
13273            ComponentName res = mServices.startServiceLocked(caller, service,
13274                    resolvedType, callingPid, callingUid, userId);
13275            Binder.restoreCallingIdentity(origId);
13276            return res;
13277        }
13278    }
13279
13280    ComponentName startServiceInPackage(int uid,
13281            Intent service, String resolvedType, int userId) {
13282        synchronized(this) {
13283            if (DEBUG_SERVICE)
13284                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13285            final long origId = Binder.clearCallingIdentity();
13286            ComponentName res = mServices.startServiceLocked(null, service,
13287                    resolvedType, -1, uid, userId);
13288            Binder.restoreCallingIdentity(origId);
13289            return res;
13290        }
13291    }
13292
13293    public int stopService(IApplicationThread caller, Intent service,
13294            String resolvedType, int userId) {
13295        enforceNotIsolatedCaller("stopService");
13296        // Refuse possible leaked file descriptors
13297        if (service != null && service.hasFileDescriptors() == true) {
13298            throw new IllegalArgumentException("File descriptors passed in Intent");
13299        }
13300
13301        synchronized(this) {
13302            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13303        }
13304    }
13305
13306    public IBinder peekService(Intent service, String resolvedType) {
13307        enforceNotIsolatedCaller("peekService");
13308        // Refuse possible leaked file descriptors
13309        if (service != null && service.hasFileDescriptors() == true) {
13310            throw new IllegalArgumentException("File descriptors passed in Intent");
13311        }
13312        synchronized(this) {
13313            return mServices.peekServiceLocked(service, resolvedType);
13314        }
13315    }
13316
13317    public boolean stopServiceToken(ComponentName className, IBinder token,
13318            int startId) {
13319        synchronized(this) {
13320            return mServices.stopServiceTokenLocked(className, token, startId);
13321        }
13322    }
13323
13324    public void setServiceForeground(ComponentName className, IBinder token,
13325            int id, Notification notification, boolean removeNotification) {
13326        synchronized(this) {
13327            mServices.setServiceForegroundLocked(className, token, id, notification,
13328                    removeNotification);
13329        }
13330    }
13331
13332    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13333            boolean requireFull, String name, String callerPackage) {
13334        final int callingUserId = UserHandle.getUserId(callingUid);
13335        if (callingUserId != userId) {
13336            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13337                if ((requireFull || checkComponentPermission(
13338                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13339                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13340                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13341                                callingPid, callingUid, -1, true)
13342                                != PackageManager.PERMISSION_GRANTED) {
13343                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13344                        // In this case, they would like to just execute as their
13345                        // owner user instead of failing.
13346                        userId = callingUserId;
13347                    } else {
13348                        StringBuilder builder = new StringBuilder(128);
13349                        builder.append("Permission Denial: ");
13350                        builder.append(name);
13351                        if (callerPackage != null) {
13352                            builder.append(" from ");
13353                            builder.append(callerPackage);
13354                        }
13355                        builder.append(" asks to run as user ");
13356                        builder.append(userId);
13357                        builder.append(" but is calling from user ");
13358                        builder.append(UserHandle.getUserId(callingUid));
13359                        builder.append("; this requires ");
13360                        builder.append(INTERACT_ACROSS_USERS_FULL);
13361                        if (!requireFull) {
13362                            builder.append(" or ");
13363                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13364                        }
13365                        String msg = builder.toString();
13366                        Slog.w(TAG, msg);
13367                        throw new SecurityException(msg);
13368                    }
13369                }
13370            }
13371            if (userId == UserHandle.USER_CURRENT
13372                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13373                // Note that we may be accessing this outside of a lock...
13374                // shouldn't be a big deal, if this is being called outside
13375                // of a locked context there is intrinsically a race with
13376                // the value the caller will receive and someone else changing it.
13377                userId = mCurrentUserId;
13378            }
13379            if (!allowAll && userId < 0) {
13380                throw new IllegalArgumentException(
13381                        "Call does not support special user #" + userId);
13382            }
13383        }
13384        return userId;
13385    }
13386
13387    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13388            String className, int flags) {
13389        boolean result = false;
13390        // For apps that don't have pre-defined UIDs, check for permission
13391        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13392            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13393                if (ActivityManager.checkUidPermission(
13394                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13395                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13396                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13397                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13398                            + " requests FLAG_SINGLE_USER, but app does not hold "
13399                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13400                    Slog.w(TAG, msg);
13401                    throw new SecurityException(msg);
13402                }
13403                // Permission passed
13404                result = true;
13405            }
13406        } else if ("system".equals(componentProcessName)) {
13407            result = true;
13408        } else {
13409            // App with pre-defined UID, check if it's a persistent app
13410            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13411        }
13412        if (DEBUG_MU) {
13413            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13414                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13415        }
13416        return result;
13417    }
13418
13419    /**
13420     * Checks to see if the caller is in the same app as the singleton
13421     * component, or the component is in a special app. It allows special apps
13422     * to export singleton components but prevents exporting singleton
13423     * components for regular apps.
13424     */
13425    boolean isValidSingletonCall(int callingUid, int componentUid) {
13426        int componentAppId = UserHandle.getAppId(componentUid);
13427        return UserHandle.isSameApp(callingUid, componentUid)
13428                || componentAppId == Process.SYSTEM_UID
13429                || componentAppId == Process.PHONE_UID
13430                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13431                        == PackageManager.PERMISSION_GRANTED;
13432    }
13433
13434    public int bindService(IApplicationThread caller, IBinder token,
13435            Intent service, String resolvedType,
13436            IServiceConnection connection, int flags, int userId) {
13437        enforceNotIsolatedCaller("bindService");
13438        // Refuse possible leaked file descriptors
13439        if (service != null && service.hasFileDescriptors() == true) {
13440            throw new IllegalArgumentException("File descriptors passed in Intent");
13441        }
13442
13443        synchronized(this) {
13444            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13445                    connection, flags, userId);
13446        }
13447    }
13448
13449    public boolean unbindService(IServiceConnection connection) {
13450        synchronized (this) {
13451            return mServices.unbindServiceLocked(connection);
13452        }
13453    }
13454
13455    public void publishService(IBinder token, Intent intent, IBinder service) {
13456        // Refuse possible leaked file descriptors
13457        if (intent != null && intent.hasFileDescriptors() == true) {
13458            throw new IllegalArgumentException("File descriptors passed in Intent");
13459        }
13460
13461        synchronized(this) {
13462            if (!(token instanceof ServiceRecord)) {
13463                throw new IllegalArgumentException("Invalid service token");
13464            }
13465            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13466        }
13467    }
13468
13469    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13470        // Refuse possible leaked file descriptors
13471        if (intent != null && intent.hasFileDescriptors() == true) {
13472            throw new IllegalArgumentException("File descriptors passed in Intent");
13473        }
13474
13475        synchronized(this) {
13476            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13477        }
13478    }
13479
13480    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13481        synchronized(this) {
13482            if (!(token instanceof ServiceRecord)) {
13483                throw new IllegalArgumentException("Invalid service token");
13484            }
13485            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13486        }
13487    }
13488
13489    // =========================================================
13490    // BACKUP AND RESTORE
13491    // =========================================================
13492
13493    // Cause the target app to be launched if necessary and its backup agent
13494    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13495    // activity manager to announce its creation.
13496    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13497        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13498        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13499
13500        synchronized(this) {
13501            // !!! TODO: currently no check here that we're already bound
13502            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13503            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13504            synchronized (stats) {
13505                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13506            }
13507
13508            // Backup agent is now in use, its package can't be stopped.
13509            try {
13510                AppGlobals.getPackageManager().setPackageStoppedState(
13511                        app.packageName, false, UserHandle.getUserId(app.uid));
13512            } catch (RemoteException e) {
13513            } catch (IllegalArgumentException e) {
13514                Slog.w(TAG, "Failed trying to unstop package "
13515                        + app.packageName + ": " + e);
13516            }
13517
13518            BackupRecord r = new BackupRecord(ss, app, backupMode);
13519            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13520                    ? new ComponentName(app.packageName, app.backupAgentName)
13521                    : new ComponentName("android", "FullBackupAgent");
13522            // startProcessLocked() returns existing proc's record if it's already running
13523            ProcessRecord proc = startProcessLocked(app.processName, app,
13524                    false, 0, "backup", hostingName, false, false, false);
13525            if (proc == null) {
13526                Slog.e(TAG, "Unable to start backup agent process " + r);
13527                return false;
13528            }
13529
13530            r.app = proc;
13531            mBackupTarget = r;
13532            mBackupAppName = app.packageName;
13533
13534            // Try not to kill the process during backup
13535            updateOomAdjLocked(proc);
13536
13537            // If the process is already attached, schedule the creation of the backup agent now.
13538            // If it is not yet live, this will be done when it attaches to the framework.
13539            if (proc.thread != null) {
13540                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13541                try {
13542                    proc.thread.scheduleCreateBackupAgent(app,
13543                            compatibilityInfoForPackageLocked(app), backupMode);
13544                } catch (RemoteException e) {
13545                    // Will time out on the backup manager side
13546                }
13547            } else {
13548                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13549            }
13550            // Invariants: at this point, the target app process exists and the application
13551            // is either already running or in the process of coming up.  mBackupTarget and
13552            // mBackupAppName describe the app, so that when it binds back to the AM we
13553            // know that it's scheduled for a backup-agent operation.
13554        }
13555
13556        return true;
13557    }
13558
13559    @Override
13560    public void clearPendingBackup() {
13561        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13562        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13563
13564        synchronized (this) {
13565            mBackupTarget = null;
13566            mBackupAppName = null;
13567        }
13568    }
13569
13570    // A backup agent has just come up
13571    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13572        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13573                + " = " + agent);
13574
13575        synchronized(this) {
13576            if (!agentPackageName.equals(mBackupAppName)) {
13577                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13578                return;
13579            }
13580        }
13581
13582        long oldIdent = Binder.clearCallingIdentity();
13583        try {
13584            IBackupManager bm = IBackupManager.Stub.asInterface(
13585                    ServiceManager.getService(Context.BACKUP_SERVICE));
13586            bm.agentConnected(agentPackageName, agent);
13587        } catch (RemoteException e) {
13588            // can't happen; the backup manager service is local
13589        } catch (Exception e) {
13590            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13591            e.printStackTrace();
13592        } finally {
13593            Binder.restoreCallingIdentity(oldIdent);
13594        }
13595    }
13596
13597    // done with this agent
13598    public void unbindBackupAgent(ApplicationInfo appInfo) {
13599        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13600        if (appInfo == null) {
13601            Slog.w(TAG, "unbind backup agent for null app");
13602            return;
13603        }
13604
13605        synchronized(this) {
13606            try {
13607                if (mBackupAppName == null) {
13608                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13609                    return;
13610                }
13611
13612                if (!mBackupAppName.equals(appInfo.packageName)) {
13613                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13614                    return;
13615                }
13616
13617                // Not backing this app up any more; reset its OOM adjustment
13618                final ProcessRecord proc = mBackupTarget.app;
13619                updateOomAdjLocked(proc);
13620
13621                // If the app crashed during backup, 'thread' will be null here
13622                if (proc.thread != null) {
13623                    try {
13624                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13625                                compatibilityInfoForPackageLocked(appInfo));
13626                    } catch (Exception e) {
13627                        Slog.e(TAG, "Exception when unbinding backup agent:");
13628                        e.printStackTrace();
13629                    }
13630                }
13631            } finally {
13632                mBackupTarget = null;
13633                mBackupAppName = null;
13634            }
13635        }
13636    }
13637    // =========================================================
13638    // BROADCASTS
13639    // =========================================================
13640
13641    private final List getStickiesLocked(String action, IntentFilter filter,
13642            List cur, int userId) {
13643        final ContentResolver resolver = mContext.getContentResolver();
13644        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13645        if (stickies == null) {
13646            return cur;
13647        }
13648        final ArrayList<Intent> list = stickies.get(action);
13649        if (list == null) {
13650            return cur;
13651        }
13652        int N = list.size();
13653        for (int i=0; i<N; i++) {
13654            Intent intent = list.get(i);
13655            if (filter.match(resolver, intent, true, TAG) >= 0) {
13656                if (cur == null) {
13657                    cur = new ArrayList<Intent>();
13658                }
13659                cur.add(intent);
13660            }
13661        }
13662        return cur;
13663    }
13664
13665    boolean isPendingBroadcastProcessLocked(int pid) {
13666        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13667                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13668    }
13669
13670    void skipPendingBroadcastLocked(int pid) {
13671            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13672            for (BroadcastQueue queue : mBroadcastQueues) {
13673                queue.skipPendingBroadcastLocked(pid);
13674            }
13675    }
13676
13677    // The app just attached; send any pending broadcasts that it should receive
13678    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13679        boolean didSomething = false;
13680        for (BroadcastQueue queue : mBroadcastQueues) {
13681            didSomething |= queue.sendPendingBroadcastsLocked(app);
13682        }
13683        return didSomething;
13684    }
13685
13686    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13687            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13688        enforceNotIsolatedCaller("registerReceiver");
13689        int callingUid;
13690        int callingPid;
13691        synchronized(this) {
13692            ProcessRecord callerApp = null;
13693            if (caller != null) {
13694                callerApp = getRecordForAppLocked(caller);
13695                if (callerApp == null) {
13696                    throw new SecurityException(
13697                            "Unable to find app for caller " + caller
13698                            + " (pid=" + Binder.getCallingPid()
13699                            + ") when registering receiver " + receiver);
13700                }
13701                if (callerApp.info.uid != Process.SYSTEM_UID &&
13702                        !callerApp.pkgList.containsKey(callerPackage) &&
13703                        !"android".equals(callerPackage)) {
13704                    throw new SecurityException("Given caller package " + callerPackage
13705                            + " is not running in process " + callerApp);
13706                }
13707                callingUid = callerApp.info.uid;
13708                callingPid = callerApp.pid;
13709            } else {
13710                callerPackage = null;
13711                callingUid = Binder.getCallingUid();
13712                callingPid = Binder.getCallingPid();
13713            }
13714
13715            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13716                    true, true, "registerReceiver", callerPackage);
13717
13718            List allSticky = null;
13719
13720            // Look for any matching sticky broadcasts...
13721            Iterator actions = filter.actionsIterator();
13722            if (actions != null) {
13723                while (actions.hasNext()) {
13724                    String action = (String)actions.next();
13725                    allSticky = getStickiesLocked(action, filter, allSticky,
13726                            UserHandle.USER_ALL);
13727                    allSticky = getStickiesLocked(action, filter, allSticky,
13728                            UserHandle.getUserId(callingUid));
13729                }
13730            } else {
13731                allSticky = getStickiesLocked(null, filter, allSticky,
13732                        UserHandle.USER_ALL);
13733                allSticky = getStickiesLocked(null, filter, allSticky,
13734                        UserHandle.getUserId(callingUid));
13735            }
13736
13737            // The first sticky in the list is returned directly back to
13738            // the client.
13739            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13740
13741            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13742                    + ": " + sticky);
13743
13744            if (receiver == null) {
13745                return sticky;
13746            }
13747
13748            ReceiverList rl
13749                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13750            if (rl == null) {
13751                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13752                        userId, receiver);
13753                if (rl.app != null) {
13754                    rl.app.receivers.add(rl);
13755                } else {
13756                    try {
13757                        receiver.asBinder().linkToDeath(rl, 0);
13758                    } catch (RemoteException e) {
13759                        return sticky;
13760                    }
13761                    rl.linkedToDeath = true;
13762                }
13763                mRegisteredReceivers.put(receiver.asBinder(), rl);
13764            } else if (rl.uid != callingUid) {
13765                throw new IllegalArgumentException(
13766                        "Receiver requested to register for uid " + callingUid
13767                        + " was previously registered for uid " + rl.uid);
13768            } else if (rl.pid != callingPid) {
13769                throw new IllegalArgumentException(
13770                        "Receiver requested to register for pid " + callingPid
13771                        + " was previously registered for pid " + rl.pid);
13772            } else if (rl.userId != userId) {
13773                throw new IllegalArgumentException(
13774                        "Receiver requested to register for user " + userId
13775                        + " was previously registered for user " + rl.userId);
13776            }
13777            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13778                    permission, callingUid, userId);
13779            rl.add(bf);
13780            if (!bf.debugCheck()) {
13781                Slog.w(TAG, "==> For Dynamic broadast");
13782            }
13783            mReceiverResolver.addFilter(bf);
13784
13785            // Enqueue broadcasts for all existing stickies that match
13786            // this filter.
13787            if (allSticky != null) {
13788                ArrayList receivers = new ArrayList();
13789                receivers.add(bf);
13790
13791                int N = allSticky.size();
13792                for (int i=0; i<N; i++) {
13793                    Intent intent = (Intent)allSticky.get(i);
13794                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13795                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13796                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13797                            null, null, false, true, true, -1);
13798                    queue.enqueueParallelBroadcastLocked(r);
13799                    queue.scheduleBroadcastsLocked();
13800                }
13801            }
13802
13803            return sticky;
13804        }
13805    }
13806
13807    public void unregisterReceiver(IIntentReceiver receiver) {
13808        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13809
13810        final long origId = Binder.clearCallingIdentity();
13811        try {
13812            boolean doTrim = false;
13813
13814            synchronized(this) {
13815                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13816                if (rl != null) {
13817                    if (rl.curBroadcast != null) {
13818                        BroadcastRecord r = rl.curBroadcast;
13819                        final boolean doNext = finishReceiverLocked(
13820                                receiver.asBinder(), r.resultCode, r.resultData,
13821                                r.resultExtras, r.resultAbort);
13822                        if (doNext) {
13823                            doTrim = true;
13824                            r.queue.processNextBroadcast(false);
13825                        }
13826                    }
13827
13828                    if (rl.app != null) {
13829                        rl.app.receivers.remove(rl);
13830                    }
13831                    removeReceiverLocked(rl);
13832                    if (rl.linkedToDeath) {
13833                        rl.linkedToDeath = false;
13834                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13835                    }
13836                }
13837            }
13838
13839            // If we actually concluded any broadcasts, we might now be able
13840            // to trim the recipients' apps from our working set
13841            if (doTrim) {
13842                trimApplications();
13843                return;
13844            }
13845
13846        } finally {
13847            Binder.restoreCallingIdentity(origId);
13848        }
13849    }
13850
13851    void removeReceiverLocked(ReceiverList rl) {
13852        mRegisteredReceivers.remove(rl.receiver.asBinder());
13853        int N = rl.size();
13854        for (int i=0; i<N; i++) {
13855            mReceiverResolver.removeFilter(rl.get(i));
13856        }
13857    }
13858
13859    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13860        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13861            ProcessRecord r = mLruProcesses.get(i);
13862            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13863                try {
13864                    r.thread.dispatchPackageBroadcast(cmd, packages);
13865                } catch (RemoteException ex) {
13866                }
13867            }
13868        }
13869    }
13870
13871    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13872            int[] users) {
13873        List<ResolveInfo> receivers = null;
13874        try {
13875            HashSet<ComponentName> singleUserReceivers = null;
13876            boolean scannedFirstReceivers = false;
13877            for (int user : users) {
13878                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13879                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13880                if (user != 0 && newReceivers != null) {
13881                    // If this is not the primary user, we need to check for
13882                    // any receivers that should be filtered out.
13883                    for (int i=0; i<newReceivers.size(); i++) {
13884                        ResolveInfo ri = newReceivers.get(i);
13885                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13886                            newReceivers.remove(i);
13887                            i--;
13888                        }
13889                    }
13890                }
13891                if (newReceivers != null && newReceivers.size() == 0) {
13892                    newReceivers = null;
13893                }
13894                if (receivers == null) {
13895                    receivers = newReceivers;
13896                } else if (newReceivers != null) {
13897                    // We need to concatenate the additional receivers
13898                    // found with what we have do far.  This would be easy,
13899                    // but we also need to de-dup any receivers that are
13900                    // singleUser.
13901                    if (!scannedFirstReceivers) {
13902                        // Collect any single user receivers we had already retrieved.
13903                        scannedFirstReceivers = true;
13904                        for (int i=0; i<receivers.size(); i++) {
13905                            ResolveInfo ri = receivers.get(i);
13906                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13907                                ComponentName cn = new ComponentName(
13908                                        ri.activityInfo.packageName, ri.activityInfo.name);
13909                                if (singleUserReceivers == null) {
13910                                    singleUserReceivers = new HashSet<ComponentName>();
13911                                }
13912                                singleUserReceivers.add(cn);
13913                            }
13914                        }
13915                    }
13916                    // Add the new results to the existing results, tracking
13917                    // and de-dupping single user receivers.
13918                    for (int i=0; i<newReceivers.size(); i++) {
13919                        ResolveInfo ri = newReceivers.get(i);
13920                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13921                            ComponentName cn = new ComponentName(
13922                                    ri.activityInfo.packageName, ri.activityInfo.name);
13923                            if (singleUserReceivers == null) {
13924                                singleUserReceivers = new HashSet<ComponentName>();
13925                            }
13926                            if (!singleUserReceivers.contains(cn)) {
13927                                singleUserReceivers.add(cn);
13928                                receivers.add(ri);
13929                            }
13930                        } else {
13931                            receivers.add(ri);
13932                        }
13933                    }
13934                }
13935            }
13936        } catch (RemoteException ex) {
13937            // pm is in same process, this will never happen.
13938        }
13939        return receivers;
13940    }
13941
13942    private final int broadcastIntentLocked(ProcessRecord callerApp,
13943            String callerPackage, Intent intent, String resolvedType,
13944            IIntentReceiver resultTo, int resultCode, String resultData,
13945            Bundle map, String requiredPermission, int appOp,
13946            boolean ordered, boolean sticky, int callingPid, int callingUid,
13947            int userId) {
13948        intent = new Intent(intent);
13949
13950        // By default broadcasts do not go to stopped apps.
13951        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13952
13953        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13954            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13955            + " ordered=" + ordered + " userid=" + userId);
13956        if ((resultTo != null) && !ordered) {
13957            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13958        }
13959
13960        userId = handleIncomingUser(callingPid, callingUid, userId,
13961                true, false, "broadcast", callerPackage);
13962
13963        // Make sure that the user who is receiving this broadcast is started.
13964        // If not, we will just skip it.
13965
13966
13967        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13968            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13969                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13970                Slog.w(TAG, "Skipping broadcast of " + intent
13971                        + ": user " + userId + " is stopped");
13972                return ActivityManager.BROADCAST_SUCCESS;
13973            }
13974        }
13975
13976        /*
13977         * Prevent non-system code (defined here to be non-persistent
13978         * processes) from sending protected broadcasts.
13979         */
13980        int callingAppId = UserHandle.getAppId(callingUid);
13981        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13982            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13983            || callingAppId == Process.NFC_UID || callingUid == 0) {
13984            // Always okay.
13985        } else if (callerApp == null || !callerApp.persistent) {
13986            try {
13987                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13988                        intent.getAction())) {
13989                    String msg = "Permission Denial: not allowed to send broadcast "
13990                            + intent.getAction() + " from pid="
13991                            + callingPid + ", uid=" + callingUid;
13992                    Slog.w(TAG, msg);
13993                    throw new SecurityException(msg);
13994                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13995                    // Special case for compatibility: we don't want apps to send this,
13996                    // but historically it has not been protected and apps may be using it
13997                    // to poke their own app widget.  So, instead of making it protected,
13998                    // just limit it to the caller.
13999                    if (callerApp == null) {
14000                        String msg = "Permission Denial: not allowed to send broadcast "
14001                                + intent.getAction() + " from unknown caller.";
14002                        Slog.w(TAG, msg);
14003                        throw new SecurityException(msg);
14004                    } else if (intent.getComponent() != null) {
14005                        // They are good enough to send to an explicit component...  verify
14006                        // it is being sent to the calling app.
14007                        if (!intent.getComponent().getPackageName().equals(
14008                                callerApp.info.packageName)) {
14009                            String msg = "Permission Denial: not allowed to send broadcast "
14010                                    + intent.getAction() + " to "
14011                                    + intent.getComponent().getPackageName() + " from "
14012                                    + callerApp.info.packageName;
14013                            Slog.w(TAG, msg);
14014                            throw new SecurityException(msg);
14015                        }
14016                    } else {
14017                        // Limit broadcast to their own package.
14018                        intent.setPackage(callerApp.info.packageName);
14019                    }
14020                }
14021            } catch (RemoteException e) {
14022                Slog.w(TAG, "Remote exception", e);
14023                return ActivityManager.BROADCAST_SUCCESS;
14024            }
14025        }
14026
14027        // Handle special intents: if this broadcast is from the package
14028        // manager about a package being removed, we need to remove all of
14029        // its activities from the history stack.
14030        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14031                intent.getAction());
14032        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14033                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14034                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14035                || uidRemoved) {
14036            if (checkComponentPermission(
14037                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14038                    callingPid, callingUid, -1, true)
14039                    == PackageManager.PERMISSION_GRANTED) {
14040                if (uidRemoved) {
14041                    final Bundle intentExtras = intent.getExtras();
14042                    final int uid = intentExtras != null
14043                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14044                    if (uid >= 0) {
14045                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14046                        synchronized (bs) {
14047                            bs.removeUidStatsLocked(uid);
14048                        }
14049                        mAppOpsService.uidRemoved(uid);
14050                    }
14051                } else {
14052                    // If resources are unavailable just force stop all
14053                    // those packages and flush the attribute cache as well.
14054                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14055                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14056                        if (list != null && (list.length > 0)) {
14057                            for (String pkg : list) {
14058                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14059                                        "storage unmount");
14060                            }
14061                            sendPackageBroadcastLocked(
14062                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14063                        }
14064                    } else {
14065                        Uri data = intent.getData();
14066                        String ssp;
14067                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14068                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14069                                    intent.getAction());
14070                            boolean fullUninstall = removed &&
14071                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14072                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14073                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14074                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14075                                        false, fullUninstall, userId,
14076                                        removed ? "pkg removed" : "pkg changed");
14077                            }
14078                            if (removed) {
14079                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14080                                        new String[] {ssp}, userId);
14081                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14082                                    mAppOpsService.packageRemoved(
14083                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14084
14085                                    // Remove all permissions granted from/to this package
14086                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14087                                }
14088                            }
14089                        }
14090                    }
14091                }
14092            } else {
14093                String msg = "Permission Denial: " + intent.getAction()
14094                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14095                        + ", uid=" + callingUid + ")"
14096                        + " requires "
14097                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14098                Slog.w(TAG, msg);
14099                throw new SecurityException(msg);
14100            }
14101
14102        // Special case for adding a package: by default turn on compatibility
14103        // mode.
14104        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14105            Uri data = intent.getData();
14106            String ssp;
14107            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14108                mCompatModePackages.handlePackageAddedLocked(ssp,
14109                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14110            }
14111        }
14112
14113        /*
14114         * If this is the time zone changed action, queue up a message that will reset the timezone
14115         * of all currently running processes. This message will get queued up before the broadcast
14116         * happens.
14117         */
14118        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14119            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14120        }
14121
14122        /*
14123         * If the user set the time, let all running processes know.
14124         */
14125        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14126            final int is24Hour = intent.getBooleanExtra(
14127                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14128            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14129        }
14130
14131        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14132            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14133        }
14134
14135        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14136            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14137            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14138        }
14139
14140        // Add to the sticky list if requested.
14141        if (sticky) {
14142            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14143                    callingPid, callingUid)
14144                    != PackageManager.PERMISSION_GRANTED) {
14145                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14146                        + callingPid + ", uid=" + callingUid
14147                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14148                Slog.w(TAG, msg);
14149                throw new SecurityException(msg);
14150            }
14151            if (requiredPermission != null) {
14152                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14153                        + " and enforce permission " + requiredPermission);
14154                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14155            }
14156            if (intent.getComponent() != null) {
14157                throw new SecurityException(
14158                        "Sticky broadcasts can't target a specific component");
14159            }
14160            // We use userId directly here, since the "all" target is maintained
14161            // as a separate set of sticky broadcasts.
14162            if (userId != UserHandle.USER_ALL) {
14163                // But first, if this is not a broadcast to all users, then
14164                // make sure it doesn't conflict with an existing broadcast to
14165                // all users.
14166                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14167                        UserHandle.USER_ALL);
14168                if (stickies != null) {
14169                    ArrayList<Intent> list = stickies.get(intent.getAction());
14170                    if (list != null) {
14171                        int N = list.size();
14172                        int i;
14173                        for (i=0; i<N; i++) {
14174                            if (intent.filterEquals(list.get(i))) {
14175                                throw new IllegalArgumentException(
14176                                        "Sticky broadcast " + intent + " for user "
14177                                        + userId + " conflicts with existing global broadcast");
14178                            }
14179                        }
14180                    }
14181                }
14182            }
14183            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14184            if (stickies == null) {
14185                stickies = new ArrayMap<String, ArrayList<Intent>>();
14186                mStickyBroadcasts.put(userId, stickies);
14187            }
14188            ArrayList<Intent> list = stickies.get(intent.getAction());
14189            if (list == null) {
14190                list = new ArrayList<Intent>();
14191                stickies.put(intent.getAction(), list);
14192            }
14193            int N = list.size();
14194            int i;
14195            for (i=0; i<N; i++) {
14196                if (intent.filterEquals(list.get(i))) {
14197                    // This sticky already exists, replace it.
14198                    list.set(i, new Intent(intent));
14199                    break;
14200                }
14201            }
14202            if (i >= N) {
14203                list.add(new Intent(intent));
14204            }
14205        }
14206
14207        int[] users;
14208        if (userId == UserHandle.USER_ALL) {
14209            // Caller wants broadcast to go to all started users.
14210            users = mStartedUserArray;
14211        } else {
14212            // Caller wants broadcast to go to one specific user.
14213            users = new int[] {userId};
14214        }
14215
14216        // Figure out who all will receive this broadcast.
14217        List receivers = null;
14218        List<BroadcastFilter> registeredReceivers = null;
14219        // Need to resolve the intent to interested receivers...
14220        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14221                 == 0) {
14222            receivers = collectReceiverComponents(intent, resolvedType, users);
14223        }
14224        if (intent.getComponent() == null) {
14225            registeredReceivers = mReceiverResolver.queryIntent(intent,
14226                    resolvedType, false, userId);
14227        }
14228
14229        final boolean replacePending =
14230                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14231
14232        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14233                + " replacePending=" + replacePending);
14234
14235        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14236        if (!ordered && NR > 0) {
14237            // If we are not serializing this broadcast, then send the
14238            // registered receivers separately so they don't wait for the
14239            // components to be launched.
14240            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14241            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14242                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14243                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14244                    ordered, sticky, false, userId);
14245            if (DEBUG_BROADCAST) Slog.v(
14246                    TAG, "Enqueueing parallel broadcast " + r);
14247            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14248            if (!replaced) {
14249                queue.enqueueParallelBroadcastLocked(r);
14250                queue.scheduleBroadcastsLocked();
14251            }
14252            registeredReceivers = null;
14253            NR = 0;
14254        }
14255
14256        // Merge into one list.
14257        int ir = 0;
14258        if (receivers != null) {
14259            // A special case for PACKAGE_ADDED: do not allow the package
14260            // being added to see this broadcast.  This prevents them from
14261            // using this as a back door to get run as soon as they are
14262            // installed.  Maybe in the future we want to have a special install
14263            // broadcast or such for apps, but we'd like to deliberately make
14264            // this decision.
14265            String skipPackages[] = null;
14266            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14267                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14268                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14269                Uri data = intent.getData();
14270                if (data != null) {
14271                    String pkgName = data.getSchemeSpecificPart();
14272                    if (pkgName != null) {
14273                        skipPackages = new String[] { pkgName };
14274                    }
14275                }
14276            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14277                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14278            }
14279            if (skipPackages != null && (skipPackages.length > 0)) {
14280                for (String skipPackage : skipPackages) {
14281                    if (skipPackage != null) {
14282                        int NT = receivers.size();
14283                        for (int it=0; it<NT; it++) {
14284                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14285                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14286                                receivers.remove(it);
14287                                it--;
14288                                NT--;
14289                            }
14290                        }
14291                    }
14292                }
14293            }
14294
14295            int NT = receivers != null ? receivers.size() : 0;
14296            int it = 0;
14297            ResolveInfo curt = null;
14298            BroadcastFilter curr = null;
14299            while (it < NT && ir < NR) {
14300                if (curt == null) {
14301                    curt = (ResolveInfo)receivers.get(it);
14302                }
14303                if (curr == null) {
14304                    curr = registeredReceivers.get(ir);
14305                }
14306                if (curr.getPriority() >= curt.priority) {
14307                    // Insert this broadcast record into the final list.
14308                    receivers.add(it, curr);
14309                    ir++;
14310                    curr = null;
14311                    it++;
14312                    NT++;
14313                } else {
14314                    // Skip to the next ResolveInfo in the final list.
14315                    it++;
14316                    curt = null;
14317                }
14318            }
14319        }
14320        while (ir < NR) {
14321            if (receivers == null) {
14322                receivers = new ArrayList();
14323            }
14324            receivers.add(registeredReceivers.get(ir));
14325            ir++;
14326        }
14327
14328        if ((receivers != null && receivers.size() > 0)
14329                || resultTo != null) {
14330            BroadcastQueue queue = broadcastQueueForIntent(intent);
14331            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14332                    callerPackage, callingPid, callingUid, resolvedType,
14333                    requiredPermission, appOp, receivers, resultTo, resultCode,
14334                    resultData, map, ordered, sticky, false, userId);
14335            if (DEBUG_BROADCAST) Slog.v(
14336                    TAG, "Enqueueing ordered broadcast " + r
14337                    + ": prev had " + queue.mOrderedBroadcasts.size());
14338            if (DEBUG_BROADCAST) {
14339                int seq = r.intent.getIntExtra("seq", -1);
14340                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14341            }
14342            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14343            if (!replaced) {
14344                queue.enqueueOrderedBroadcastLocked(r);
14345                queue.scheduleBroadcastsLocked();
14346            }
14347        }
14348
14349        return ActivityManager.BROADCAST_SUCCESS;
14350    }
14351
14352    final Intent verifyBroadcastLocked(Intent intent) {
14353        // Refuse possible leaked file descriptors
14354        if (intent != null && intent.hasFileDescriptors() == true) {
14355            throw new IllegalArgumentException("File descriptors passed in Intent");
14356        }
14357
14358        int flags = intent.getFlags();
14359
14360        if (!mProcessesReady) {
14361            // if the caller really truly claims to know what they're doing, go
14362            // ahead and allow the broadcast without launching any receivers
14363            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14364                intent = new Intent(intent);
14365                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14366            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14367                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14368                        + " before boot completion");
14369                throw new IllegalStateException("Cannot broadcast before boot completed");
14370            }
14371        }
14372
14373        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14374            throw new IllegalArgumentException(
14375                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14376        }
14377
14378        return intent;
14379    }
14380
14381    public final int broadcastIntent(IApplicationThread caller,
14382            Intent intent, String resolvedType, IIntentReceiver resultTo,
14383            int resultCode, String resultData, Bundle map,
14384            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14385        enforceNotIsolatedCaller("broadcastIntent");
14386        synchronized(this) {
14387            intent = verifyBroadcastLocked(intent);
14388
14389            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14390            final int callingPid = Binder.getCallingPid();
14391            final int callingUid = Binder.getCallingUid();
14392            final long origId = Binder.clearCallingIdentity();
14393            int res = broadcastIntentLocked(callerApp,
14394                    callerApp != null ? callerApp.info.packageName : null,
14395                    intent, resolvedType, resultTo,
14396                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14397                    callingPid, callingUid, userId);
14398            Binder.restoreCallingIdentity(origId);
14399            return res;
14400        }
14401    }
14402
14403    int broadcastIntentInPackage(String packageName, int uid,
14404            Intent intent, String resolvedType, IIntentReceiver resultTo,
14405            int resultCode, String resultData, Bundle map,
14406            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14407        synchronized(this) {
14408            intent = verifyBroadcastLocked(intent);
14409
14410            final long origId = Binder.clearCallingIdentity();
14411            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14412                    resultTo, resultCode, resultData, map, requiredPermission,
14413                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14414            Binder.restoreCallingIdentity(origId);
14415            return res;
14416        }
14417    }
14418
14419    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14420        // Refuse possible leaked file descriptors
14421        if (intent != null && intent.hasFileDescriptors() == true) {
14422            throw new IllegalArgumentException("File descriptors passed in Intent");
14423        }
14424
14425        userId = handleIncomingUser(Binder.getCallingPid(),
14426                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14427
14428        synchronized(this) {
14429            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14430                    != PackageManager.PERMISSION_GRANTED) {
14431                String msg = "Permission Denial: unbroadcastIntent() from pid="
14432                        + Binder.getCallingPid()
14433                        + ", uid=" + Binder.getCallingUid()
14434                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14435                Slog.w(TAG, msg);
14436                throw new SecurityException(msg);
14437            }
14438            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14439            if (stickies != null) {
14440                ArrayList<Intent> list = stickies.get(intent.getAction());
14441                if (list != null) {
14442                    int N = list.size();
14443                    int i;
14444                    for (i=0; i<N; i++) {
14445                        if (intent.filterEquals(list.get(i))) {
14446                            list.remove(i);
14447                            break;
14448                        }
14449                    }
14450                    if (list.size() <= 0) {
14451                        stickies.remove(intent.getAction());
14452                    }
14453                }
14454                if (stickies.size() <= 0) {
14455                    mStickyBroadcasts.remove(userId);
14456                }
14457            }
14458        }
14459    }
14460
14461    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14462            String resultData, Bundle resultExtras, boolean resultAbort) {
14463        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14464        if (r == null) {
14465            Slog.w(TAG, "finishReceiver called but not found on queue");
14466            return false;
14467        }
14468
14469        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14470    }
14471
14472    void backgroundServicesFinishedLocked(int userId) {
14473        for (BroadcastQueue queue : mBroadcastQueues) {
14474            queue.backgroundServicesFinishedLocked(userId);
14475        }
14476    }
14477
14478    public void finishReceiver(IBinder who, int resultCode, String resultData,
14479            Bundle resultExtras, boolean resultAbort) {
14480        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14481
14482        // Refuse possible leaked file descriptors
14483        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14484            throw new IllegalArgumentException("File descriptors passed in Bundle");
14485        }
14486
14487        final long origId = Binder.clearCallingIdentity();
14488        try {
14489            boolean doNext = false;
14490            BroadcastRecord r;
14491
14492            synchronized(this) {
14493                r = broadcastRecordForReceiverLocked(who);
14494                if (r != null) {
14495                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14496                        resultData, resultExtras, resultAbort, true);
14497                }
14498            }
14499
14500            if (doNext) {
14501                r.queue.processNextBroadcast(false);
14502            }
14503            trimApplications();
14504        } finally {
14505            Binder.restoreCallingIdentity(origId);
14506        }
14507    }
14508
14509    // =========================================================
14510    // INSTRUMENTATION
14511    // =========================================================
14512
14513    public boolean startInstrumentation(ComponentName className,
14514            String profileFile, int flags, Bundle arguments,
14515            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14516            int userId, String abiOverride) {
14517        enforceNotIsolatedCaller("startInstrumentation");
14518        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14519                userId, false, true, "startInstrumentation", null);
14520        // Refuse possible leaked file descriptors
14521        if (arguments != null && arguments.hasFileDescriptors()) {
14522            throw new IllegalArgumentException("File descriptors passed in Bundle");
14523        }
14524
14525        synchronized(this) {
14526            InstrumentationInfo ii = null;
14527            ApplicationInfo ai = null;
14528            try {
14529                ii = mContext.getPackageManager().getInstrumentationInfo(
14530                    className, STOCK_PM_FLAGS);
14531                ai = AppGlobals.getPackageManager().getApplicationInfo(
14532                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14533            } catch (PackageManager.NameNotFoundException e) {
14534            } catch (RemoteException e) {
14535            }
14536            if (ii == null) {
14537                reportStartInstrumentationFailure(watcher, className,
14538                        "Unable to find instrumentation info for: " + className);
14539                return false;
14540            }
14541            if (ai == null) {
14542                reportStartInstrumentationFailure(watcher, className,
14543                        "Unable to find instrumentation target package: " + ii.targetPackage);
14544                return false;
14545            }
14546
14547            int match = mContext.getPackageManager().checkSignatures(
14548                    ii.targetPackage, ii.packageName);
14549            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14550                String msg = "Permission Denial: starting instrumentation "
14551                        + className + " from pid="
14552                        + Binder.getCallingPid()
14553                        + ", uid=" + Binder.getCallingPid()
14554                        + " not allowed because package " + ii.packageName
14555                        + " does not have a signature matching the target "
14556                        + ii.targetPackage;
14557                reportStartInstrumentationFailure(watcher, className, msg);
14558                throw new SecurityException(msg);
14559            }
14560
14561            final long origId = Binder.clearCallingIdentity();
14562            // Instrumentation can kill and relaunch even persistent processes
14563            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14564                    "start instr");
14565            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14566            app.instrumentationClass = className;
14567            app.instrumentationInfo = ai;
14568            app.instrumentationProfileFile = profileFile;
14569            app.instrumentationArguments = arguments;
14570            app.instrumentationWatcher = watcher;
14571            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14572            app.instrumentationResultClass = className;
14573            Binder.restoreCallingIdentity(origId);
14574        }
14575
14576        return true;
14577    }
14578
14579    /**
14580     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14581     * error to the logs, but if somebody is watching, send the report there too.  This enables
14582     * the "am" command to report errors with more information.
14583     *
14584     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14585     * @param cn The component name of the instrumentation.
14586     * @param report The error report.
14587     */
14588    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14589            ComponentName cn, String report) {
14590        Slog.w(TAG, report);
14591        try {
14592            if (watcher != null) {
14593                Bundle results = new Bundle();
14594                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14595                results.putString("Error", report);
14596                watcher.instrumentationStatus(cn, -1, results);
14597            }
14598        } catch (RemoteException e) {
14599            Slog.w(TAG, e);
14600        }
14601    }
14602
14603    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14604        if (app.instrumentationWatcher != null) {
14605            try {
14606                // NOTE:  IInstrumentationWatcher *must* be oneway here
14607                app.instrumentationWatcher.instrumentationFinished(
14608                    app.instrumentationClass,
14609                    resultCode,
14610                    results);
14611            } catch (RemoteException e) {
14612            }
14613        }
14614        if (app.instrumentationUiAutomationConnection != null) {
14615            try {
14616                app.instrumentationUiAutomationConnection.shutdown();
14617            } catch (RemoteException re) {
14618                /* ignore */
14619            }
14620            // Only a UiAutomation can set this flag and now that
14621            // it is finished we make sure it is reset to its default.
14622            mUserIsMonkey = false;
14623        }
14624        app.instrumentationWatcher = null;
14625        app.instrumentationUiAutomationConnection = null;
14626        app.instrumentationClass = null;
14627        app.instrumentationInfo = null;
14628        app.instrumentationProfileFile = null;
14629        app.instrumentationArguments = null;
14630
14631        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14632                "finished inst");
14633    }
14634
14635    public void finishInstrumentation(IApplicationThread target,
14636            int resultCode, Bundle results) {
14637        int userId = UserHandle.getCallingUserId();
14638        // Refuse possible leaked file descriptors
14639        if (results != null && results.hasFileDescriptors()) {
14640            throw new IllegalArgumentException("File descriptors passed in Intent");
14641        }
14642
14643        synchronized(this) {
14644            ProcessRecord app = getRecordForAppLocked(target);
14645            if (app == null) {
14646                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14647                return;
14648            }
14649            final long origId = Binder.clearCallingIdentity();
14650            finishInstrumentationLocked(app, resultCode, results);
14651            Binder.restoreCallingIdentity(origId);
14652        }
14653    }
14654
14655    // =========================================================
14656    // CONFIGURATION
14657    // =========================================================
14658
14659    public ConfigurationInfo getDeviceConfigurationInfo() {
14660        ConfigurationInfo config = new ConfigurationInfo();
14661        synchronized (this) {
14662            config.reqTouchScreen = mConfiguration.touchscreen;
14663            config.reqKeyboardType = mConfiguration.keyboard;
14664            config.reqNavigation = mConfiguration.navigation;
14665            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14666                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14667                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14668            }
14669            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14670                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14671                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14672            }
14673            config.reqGlEsVersion = GL_ES_VERSION;
14674        }
14675        return config;
14676    }
14677
14678    ActivityStack getFocusedStack() {
14679        return mStackSupervisor.getFocusedStack();
14680    }
14681
14682    public Configuration getConfiguration() {
14683        Configuration ci;
14684        synchronized(this) {
14685            ci = new Configuration(mConfiguration);
14686        }
14687        return ci;
14688    }
14689
14690    public void updatePersistentConfiguration(Configuration values) {
14691        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14692                "updateConfiguration()");
14693        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14694                "updateConfiguration()");
14695        if (values == null) {
14696            throw new NullPointerException("Configuration must not be null");
14697        }
14698
14699        synchronized(this) {
14700            final long origId = Binder.clearCallingIdentity();
14701            updateConfigurationLocked(values, null, true, false);
14702            Binder.restoreCallingIdentity(origId);
14703        }
14704    }
14705
14706    public void updateConfiguration(Configuration values) {
14707        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14708                "updateConfiguration()");
14709
14710        synchronized(this) {
14711            if (values == null && mWindowManager != null) {
14712                // sentinel: fetch the current configuration from the window manager
14713                values = mWindowManager.computeNewConfiguration();
14714            }
14715
14716            if (mWindowManager != null) {
14717                mProcessList.applyDisplaySize(mWindowManager);
14718            }
14719
14720            final long origId = Binder.clearCallingIdentity();
14721            if (values != null) {
14722                Settings.System.clearConfiguration(values);
14723            }
14724            updateConfigurationLocked(values, null, false, false);
14725            Binder.restoreCallingIdentity(origId);
14726        }
14727    }
14728
14729    /**
14730     * Do either or both things: (1) change the current configuration, and (2)
14731     * make sure the given activity is running with the (now) current
14732     * configuration.  Returns true if the activity has been left running, or
14733     * false if <var>starting</var> is being destroyed to match the new
14734     * configuration.
14735     * @param persistent TODO
14736     */
14737    boolean updateConfigurationLocked(Configuration values,
14738            ActivityRecord starting, boolean persistent, boolean initLocale) {
14739        int changes = 0;
14740
14741        if (values != null) {
14742            Configuration newConfig = new Configuration(mConfiguration);
14743            changes = newConfig.updateFrom(values);
14744            if (changes != 0) {
14745                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14746                    Slog.i(TAG, "Updating configuration to: " + values);
14747                }
14748
14749                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14750
14751                if (values.locale != null && !initLocale) {
14752                    saveLocaleLocked(values.locale,
14753                                     !values.locale.equals(mConfiguration.locale),
14754                                     values.userSetLocale);
14755                }
14756
14757                mConfigurationSeq++;
14758                if (mConfigurationSeq <= 0) {
14759                    mConfigurationSeq = 1;
14760                }
14761                newConfig.seq = mConfigurationSeq;
14762                mConfiguration = newConfig;
14763                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14764                mUsageStatsService.noteStartConfig(newConfig);
14765
14766                final Configuration configCopy = new Configuration(mConfiguration);
14767
14768                // TODO: If our config changes, should we auto dismiss any currently
14769                // showing dialogs?
14770                mShowDialogs = shouldShowDialogs(newConfig);
14771
14772                AttributeCache ac = AttributeCache.instance();
14773                if (ac != null) {
14774                    ac.updateConfiguration(configCopy);
14775                }
14776
14777                // Make sure all resources in our process are updated
14778                // right now, so that anyone who is going to retrieve
14779                // resource values after we return will be sure to get
14780                // the new ones.  This is especially important during
14781                // boot, where the first config change needs to guarantee
14782                // all resources have that config before following boot
14783                // code is executed.
14784                mSystemThread.applyConfigurationToResources(configCopy);
14785
14786                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14787                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14788                    msg.obj = new Configuration(configCopy);
14789                    mHandler.sendMessage(msg);
14790                }
14791
14792                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14793                    ProcessRecord app = mLruProcesses.get(i);
14794                    try {
14795                        if (app.thread != null) {
14796                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14797                                    + app.processName + " new config " + mConfiguration);
14798                            app.thread.scheduleConfigurationChanged(configCopy);
14799                        }
14800                    } catch (Exception e) {
14801                    }
14802                }
14803                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14804                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14805                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14806                        | Intent.FLAG_RECEIVER_FOREGROUND);
14807                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14808                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14809                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14810                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14811                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14812                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14813                    broadcastIntentLocked(null, null, intent,
14814                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14815                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14816                }
14817            }
14818        }
14819
14820        boolean kept = true;
14821        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14822        // mainStack is null during startup.
14823        if (mainStack != null) {
14824            if (changes != 0 && starting == null) {
14825                // If the configuration changed, and the caller is not already
14826                // in the process of starting an activity, then find the top
14827                // activity to check if its configuration needs to change.
14828                starting = mainStack.topRunningActivityLocked(null);
14829            }
14830
14831            if (starting != null) {
14832                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14833                // And we need to make sure at this point that all other activities
14834                // are made visible with the correct configuration.
14835                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14836            }
14837        }
14838
14839        if (values != null && mWindowManager != null) {
14840            mWindowManager.setNewConfiguration(mConfiguration);
14841        }
14842
14843        return kept;
14844    }
14845
14846    /**
14847     * Decide based on the configuration whether we should shouw the ANR,
14848     * crash, etc dialogs.  The idea is that if there is no affordnace to
14849     * press the on-screen buttons, we shouldn't show the dialog.
14850     *
14851     * A thought: SystemUI might also want to get told about this, the Power
14852     * dialog / global actions also might want different behaviors.
14853     */
14854    private static final boolean shouldShowDialogs(Configuration config) {
14855        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14856                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14857    }
14858
14859    /**
14860     * Save the locale.  You must be inside a synchronized (this) block.
14861     */
14862    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14863        if(isDiff) {
14864            SystemProperties.set("user.language", l.getLanguage());
14865            SystemProperties.set("user.region", l.getCountry());
14866        }
14867
14868        if(isPersist) {
14869            SystemProperties.set("persist.sys.language", l.getLanguage());
14870            SystemProperties.set("persist.sys.country", l.getCountry());
14871            SystemProperties.set("persist.sys.localevar", l.getVariant());
14872        }
14873    }
14874
14875    @Override
14876    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14877        ActivityRecord srec = ActivityRecord.forToken(token);
14878        return srec != null && srec.task.affinity != null &&
14879                srec.task.affinity.equals(destAffinity);
14880    }
14881
14882    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14883            Intent resultData) {
14884
14885        synchronized (this) {
14886            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14887            if (stack != null) {
14888                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14889            }
14890            return false;
14891        }
14892    }
14893
14894    public int getLaunchedFromUid(IBinder activityToken) {
14895        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14896        if (srec == null) {
14897            return -1;
14898        }
14899        return srec.launchedFromUid;
14900    }
14901
14902    public String getLaunchedFromPackage(IBinder activityToken) {
14903        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14904        if (srec == null) {
14905            return null;
14906        }
14907        return srec.launchedFromPackage;
14908    }
14909
14910    // =========================================================
14911    // LIFETIME MANAGEMENT
14912    // =========================================================
14913
14914    // Returns which broadcast queue the app is the current [or imminent] receiver
14915    // on, or 'null' if the app is not an active broadcast recipient.
14916    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14917        BroadcastRecord r = app.curReceiver;
14918        if (r != null) {
14919            return r.queue;
14920        }
14921
14922        // It's not the current receiver, but it might be starting up to become one
14923        synchronized (this) {
14924            for (BroadcastQueue queue : mBroadcastQueues) {
14925                r = queue.mPendingBroadcast;
14926                if (r != null && r.curApp == app) {
14927                    // found it; report which queue it's in
14928                    return queue;
14929                }
14930            }
14931        }
14932
14933        return null;
14934    }
14935
14936    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14937            boolean doingAll, long now) {
14938        if (mAdjSeq == app.adjSeq) {
14939            // This adjustment has already been computed.
14940            return app.curRawAdj;
14941        }
14942
14943        if (app.thread == null) {
14944            app.adjSeq = mAdjSeq;
14945            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14946            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14947            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14948        }
14949
14950        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14951        app.adjSource = null;
14952        app.adjTarget = null;
14953        app.empty = false;
14954        app.cached = false;
14955
14956        final int activitiesSize = app.activities.size();
14957
14958        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14959            // The max adjustment doesn't allow this app to be anything
14960            // below foreground, so it is not worth doing work for it.
14961            app.adjType = "fixed";
14962            app.adjSeq = mAdjSeq;
14963            app.curRawAdj = app.maxAdj;
14964            app.foregroundActivities = false;
14965            app.keeping = true;
14966            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14967            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14968            // System processes can do UI, and when they do we want to have
14969            // them trim their memory after the user leaves the UI.  To
14970            // facilitate this, here we need to determine whether or not it
14971            // is currently showing UI.
14972            app.systemNoUi = true;
14973            if (app == TOP_APP) {
14974                app.systemNoUi = false;
14975            } else if (activitiesSize > 0) {
14976                for (int j = 0; j < activitiesSize; j++) {
14977                    final ActivityRecord r = app.activities.get(j);
14978                    if (r.visible) {
14979                        app.systemNoUi = false;
14980                    }
14981                }
14982            }
14983            if (!app.systemNoUi) {
14984                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14985            }
14986            return (app.curAdj=app.maxAdj);
14987        }
14988
14989        app.keeping = false;
14990        app.systemNoUi = false;
14991
14992        // Determine the importance of the process, starting with most
14993        // important to least, and assign an appropriate OOM adjustment.
14994        int adj;
14995        int schedGroup;
14996        int procState;
14997        boolean foregroundActivities = false;
14998        BroadcastQueue queue;
14999        if (app == TOP_APP) {
15000            // The last app on the list is the foreground app.
15001            adj = ProcessList.FOREGROUND_APP_ADJ;
15002            schedGroup = Process.THREAD_GROUP_DEFAULT;
15003            app.adjType = "top-activity";
15004            foregroundActivities = true;
15005            procState = ActivityManager.PROCESS_STATE_TOP;
15006        } else if (app.instrumentationClass != null) {
15007            // Don't want to kill running instrumentation.
15008            adj = ProcessList.FOREGROUND_APP_ADJ;
15009            schedGroup = Process.THREAD_GROUP_DEFAULT;
15010            app.adjType = "instrumentation";
15011            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15012        } else if ((queue = isReceivingBroadcast(app)) != null) {
15013            // An app that is currently receiving a broadcast also
15014            // counts as being in the foreground for OOM killer purposes.
15015            // It's placed in a sched group based on the nature of the
15016            // broadcast as reflected by which queue it's active in.
15017            adj = ProcessList.FOREGROUND_APP_ADJ;
15018            schedGroup = (queue == mFgBroadcastQueue)
15019                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15020            app.adjType = "broadcast";
15021            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15022        } else if (app.executingServices.size() > 0) {
15023            // An app that is currently executing a service callback also
15024            // counts as being in the foreground.
15025            adj = ProcessList.FOREGROUND_APP_ADJ;
15026            schedGroup = app.execServicesFg ?
15027                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15028            app.adjType = "exec-service";
15029            procState = ActivityManager.PROCESS_STATE_SERVICE;
15030            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15031        } else {
15032            // As far as we know the process is empty.  We may change our mind later.
15033            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15034            // At this point we don't actually know the adjustment.  Use the cached adj
15035            // value that the caller wants us to.
15036            adj = cachedAdj;
15037            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15038            app.cached = true;
15039            app.empty = true;
15040            app.adjType = "cch-empty";
15041        }
15042
15043        // Examine all activities if not already foreground.
15044        if (!foregroundActivities && activitiesSize > 0) {
15045            for (int j = 0; j < activitiesSize; j++) {
15046                final ActivityRecord r = app.activities.get(j);
15047                if (r.app != app) {
15048                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15049                            + app + "?!?");
15050                    continue;
15051                }
15052                if (r.visible) {
15053                    // App has a visible activity; only upgrade adjustment.
15054                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15055                        adj = ProcessList.VISIBLE_APP_ADJ;
15056                        app.adjType = "visible";
15057                    }
15058                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15059                        procState = ActivityManager.PROCESS_STATE_TOP;
15060                    }
15061                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15062                    app.cached = false;
15063                    app.empty = false;
15064                    foregroundActivities = true;
15065                    break;
15066                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15067                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15068                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15069                        app.adjType = "pausing";
15070                    }
15071                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15072                        procState = ActivityManager.PROCESS_STATE_TOP;
15073                    }
15074                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15075                    app.cached = false;
15076                    app.empty = false;
15077                    foregroundActivities = true;
15078                } else if (r.state == ActivityState.STOPPING) {
15079                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15080                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15081                        app.adjType = "stopping";
15082                    }
15083                    // For the process state, we will at this point consider the
15084                    // process to be cached.  It will be cached either as an activity
15085                    // or empty depending on whether the activity is finishing.  We do
15086                    // this so that we can treat the process as cached for purposes of
15087                    // memory trimming (determing current memory level, trim command to
15088                    // send to process) since there can be an arbitrary number of stopping
15089                    // processes and they should soon all go into the cached state.
15090                    if (!r.finishing) {
15091                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15092                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15093                        }
15094                    }
15095                    app.cached = false;
15096                    app.empty = false;
15097                    foregroundActivities = true;
15098                } else {
15099                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15100                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15101                        app.adjType = "cch-act";
15102                    }
15103                }
15104            }
15105        }
15106
15107        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15108            if (app.foregroundServices) {
15109                // The user is aware of this app, so make it visible.
15110                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15111                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15112                app.cached = false;
15113                app.adjType = "fg-service";
15114                schedGroup = Process.THREAD_GROUP_DEFAULT;
15115            } else if (app.forcingToForeground != null) {
15116                // The user is aware of this app, so make it visible.
15117                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15118                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15119                app.cached = false;
15120                app.adjType = "force-fg";
15121                app.adjSource = app.forcingToForeground;
15122                schedGroup = Process.THREAD_GROUP_DEFAULT;
15123            }
15124        }
15125
15126        if (app == mHeavyWeightProcess) {
15127            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15128                // We don't want to kill the current heavy-weight process.
15129                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15130                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15131                app.cached = false;
15132                app.adjType = "heavy";
15133            }
15134            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15135                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15136            }
15137        }
15138
15139        if (app == mHomeProcess) {
15140            if (adj > ProcessList.HOME_APP_ADJ) {
15141                // This process is hosting what we currently consider to be the
15142                // home app, so we don't want to let it go into the background.
15143                adj = ProcessList.HOME_APP_ADJ;
15144                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15145                app.cached = false;
15146                app.adjType = "home";
15147            }
15148            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15149                procState = ActivityManager.PROCESS_STATE_HOME;
15150            }
15151        }
15152
15153        if (app == mPreviousProcess && app.activities.size() > 0) {
15154            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15155                // This was the previous process that showed UI to the user.
15156                // We want to try to keep it around more aggressively, to give
15157                // a good experience around switching between two apps.
15158                adj = ProcessList.PREVIOUS_APP_ADJ;
15159                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15160                app.cached = false;
15161                app.adjType = "previous";
15162            }
15163            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15164                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15165            }
15166        }
15167
15168        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15169                + " reason=" + app.adjType);
15170
15171        // By default, we use the computed adjustment.  It may be changed if
15172        // there are applications dependent on our services or providers, but
15173        // this gives us a baseline and makes sure we don't get into an
15174        // infinite recursion.
15175        app.adjSeq = mAdjSeq;
15176        app.curRawAdj = adj;
15177        app.hasStartedServices = false;
15178
15179        if (mBackupTarget != null && app == mBackupTarget.app) {
15180            // If possible we want to avoid killing apps while they're being backed up
15181            if (adj > ProcessList.BACKUP_APP_ADJ) {
15182                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15183                adj = ProcessList.BACKUP_APP_ADJ;
15184                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15185                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15186                }
15187                app.adjType = "backup";
15188                app.cached = false;
15189            }
15190            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15191                procState = ActivityManager.PROCESS_STATE_BACKUP;
15192            }
15193        }
15194
15195        boolean mayBeTop = false;
15196
15197        for (int is = app.services.size()-1;
15198                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15199                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15200                        || procState > ActivityManager.PROCESS_STATE_TOP);
15201                is--) {
15202            ServiceRecord s = app.services.valueAt(is);
15203            if (s.startRequested) {
15204                app.hasStartedServices = true;
15205                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15206                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15207                }
15208                if (app.hasShownUi && app != mHomeProcess) {
15209                    // If this process has shown some UI, let it immediately
15210                    // go to the LRU list because it may be pretty heavy with
15211                    // UI stuff.  We'll tag it with a label just to help
15212                    // debug and understand what is going on.
15213                    if (adj > ProcessList.SERVICE_ADJ) {
15214                        app.adjType = "cch-started-ui-services";
15215                    }
15216                } else {
15217                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15218                        // This service has seen some activity within
15219                        // recent memory, so we will keep its process ahead
15220                        // of the background processes.
15221                        if (adj > ProcessList.SERVICE_ADJ) {
15222                            adj = ProcessList.SERVICE_ADJ;
15223                            app.adjType = "started-services";
15224                            app.cached = false;
15225                        }
15226                    }
15227                    // If we have let the service slide into the background
15228                    // state, still have some text describing what it is doing
15229                    // even though the service no longer has an impact.
15230                    if (adj > ProcessList.SERVICE_ADJ) {
15231                        app.adjType = "cch-started-services";
15232                    }
15233                }
15234                // Don't kill this process because it is doing work; it
15235                // has said it is doing work.
15236                app.keeping = true;
15237            }
15238            for (int conni = s.connections.size()-1;
15239                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15240                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15241                            || procState > ActivityManager.PROCESS_STATE_TOP);
15242                    conni--) {
15243                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15244                for (int i = 0;
15245                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15246                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15247                                || procState > ActivityManager.PROCESS_STATE_TOP);
15248                        i++) {
15249                    // XXX should compute this based on the max of
15250                    // all connected clients.
15251                    ConnectionRecord cr = clist.get(i);
15252                    if (cr.binding.client == app) {
15253                        // Binding to ourself is not interesting.
15254                        continue;
15255                    }
15256                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15257                        ProcessRecord client = cr.binding.client;
15258                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15259                                TOP_APP, doingAll, now);
15260                        int clientProcState = client.curProcState;
15261                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15262                            // If the other app is cached for any reason, for purposes here
15263                            // we are going to consider it empty.  The specific cached state
15264                            // doesn't propagate except under certain conditions.
15265                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15266                        }
15267                        String adjType = null;
15268                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15269                            // Not doing bind OOM management, so treat
15270                            // this guy more like a started service.
15271                            if (app.hasShownUi && app != mHomeProcess) {
15272                                // If this process has shown some UI, let it immediately
15273                                // go to the LRU list because it may be pretty heavy with
15274                                // UI stuff.  We'll tag it with a label just to help
15275                                // debug and understand what is going on.
15276                                if (adj > clientAdj) {
15277                                    adjType = "cch-bound-ui-services";
15278                                }
15279                                app.cached = false;
15280                                clientAdj = adj;
15281                                clientProcState = procState;
15282                            } else {
15283                                if (now >= (s.lastActivity
15284                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15285                                    // This service has not seen activity within
15286                                    // recent memory, so allow it to drop to the
15287                                    // LRU list if there is no other reason to keep
15288                                    // it around.  We'll also tag it with a label just
15289                                    // to help debug and undertand what is going on.
15290                                    if (adj > clientAdj) {
15291                                        adjType = "cch-bound-services";
15292                                    }
15293                                    clientAdj = adj;
15294                                }
15295                            }
15296                        }
15297                        if (adj > clientAdj) {
15298                            // If this process has recently shown UI, and
15299                            // the process that is binding to it is less
15300                            // important than being visible, then we don't
15301                            // care about the binding as much as we care
15302                            // about letting this process get into the LRU
15303                            // list to be killed and restarted if needed for
15304                            // memory.
15305                            if (app.hasShownUi && app != mHomeProcess
15306                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15307                                adjType = "cch-bound-ui-services";
15308                            } else {
15309                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15310                                        |Context.BIND_IMPORTANT)) != 0) {
15311                                    adj = clientAdj;
15312                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15313                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15314                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15315                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15316                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15317                                    adj = clientAdj;
15318                                } else {
15319                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15320                                        adj = ProcessList.VISIBLE_APP_ADJ;
15321                                    }
15322                                }
15323                                if (!client.cached) {
15324                                    app.cached = false;
15325                                }
15326                                if (client.keeping) {
15327                                    app.keeping = true;
15328                                }
15329                                adjType = "service";
15330                            }
15331                        }
15332                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15333                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15334                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15335                            }
15336                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15337                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15338                                    // Special handling of clients who are in the top state.
15339                                    // We *may* want to consider this process to be in the
15340                                    // top state as well, but only if there is not another
15341                                    // reason for it to be running.  Being on the top is a
15342                                    // special state, meaning you are specifically running
15343                                    // for the current top app.  If the process is already
15344                                    // running in the background for some other reason, it
15345                                    // is more important to continue considering it to be
15346                                    // in the background state.
15347                                    mayBeTop = true;
15348                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15349                                } else {
15350                                    // Special handling for above-top states (persistent
15351                                    // processes).  These should not bring the current process
15352                                    // into the top state, since they are not on top.  Instead
15353                                    // give them the best state after that.
15354                                    clientProcState =
15355                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15356                                }
15357                            }
15358                        } else {
15359                            if (clientProcState <
15360                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15361                                clientProcState =
15362                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15363                            }
15364                        }
15365                        if (procState > clientProcState) {
15366                            procState = clientProcState;
15367                        }
15368                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15369                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15370                            app.pendingUiClean = true;
15371                        }
15372                        if (adjType != null) {
15373                            app.adjType = adjType;
15374                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15375                                    .REASON_SERVICE_IN_USE;
15376                            app.adjSource = cr.binding.client;
15377                            app.adjSourceOom = clientAdj;
15378                            app.adjTarget = s.name;
15379                        }
15380                    }
15381                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15382                        app.treatLikeActivity = true;
15383                    }
15384                    final ActivityRecord a = cr.activity;
15385                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15386                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15387                                (a.visible || a.state == ActivityState.RESUMED
15388                                 || a.state == ActivityState.PAUSING)) {
15389                            adj = ProcessList.FOREGROUND_APP_ADJ;
15390                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15391                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15392                            }
15393                            app.cached = false;
15394                            app.adjType = "service";
15395                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15396                                    .REASON_SERVICE_IN_USE;
15397                            app.adjSource = a;
15398                            app.adjSourceOom = adj;
15399                            app.adjTarget = s.name;
15400                        }
15401                    }
15402                }
15403            }
15404        }
15405
15406        for (int provi = app.pubProviders.size()-1;
15407                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15408                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15409                        || procState > ActivityManager.PROCESS_STATE_TOP);
15410                provi--) {
15411            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15412            for (int i = cpr.connections.size()-1;
15413                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15414                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15415                            || procState > ActivityManager.PROCESS_STATE_TOP);
15416                    i--) {
15417                ContentProviderConnection conn = cpr.connections.get(i);
15418                ProcessRecord client = conn.client;
15419                if (client == app) {
15420                    // Being our own client is not interesting.
15421                    continue;
15422                }
15423                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15424                int clientProcState = client.curProcState;
15425                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15426                    // If the other app is cached for any reason, for purposes here
15427                    // we are going to consider it empty.
15428                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15429                }
15430                if (adj > clientAdj) {
15431                    if (app.hasShownUi && app != mHomeProcess
15432                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15433                        app.adjType = "cch-ui-provider";
15434                    } else {
15435                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15436                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15437                        app.adjType = "provider";
15438                    }
15439                    app.cached &= client.cached;
15440                    app.keeping |= client.keeping;
15441                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15442                            .REASON_PROVIDER_IN_USE;
15443                    app.adjSource = client;
15444                    app.adjSourceOom = clientAdj;
15445                    app.adjTarget = cpr.name;
15446                }
15447                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15448                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15449                        // Special handling of clients who are in the top state.
15450                        // We *may* want to consider this process to be in the
15451                        // top state as well, but only if there is not another
15452                        // reason for it to be running.  Being on the top is a
15453                        // special state, meaning you are specifically running
15454                        // for the current top app.  If the process is already
15455                        // running in the background for some other reason, it
15456                        // is more important to continue considering it to be
15457                        // in the background state.
15458                        mayBeTop = true;
15459                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15460                    } else {
15461                        // Special handling for above-top states (persistent
15462                        // processes).  These should not bring the current process
15463                        // into the top state, since they are not on top.  Instead
15464                        // give them the best state after that.
15465                        clientProcState =
15466                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15467                    }
15468                }
15469                if (procState > clientProcState) {
15470                    procState = clientProcState;
15471                }
15472                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15473                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15474                }
15475            }
15476            // If the provider has external (non-framework) process
15477            // dependencies, ensure that its adjustment is at least
15478            // FOREGROUND_APP_ADJ.
15479            if (cpr.hasExternalProcessHandles()) {
15480                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15481                    adj = ProcessList.FOREGROUND_APP_ADJ;
15482                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15483                    app.cached = false;
15484                    app.keeping = true;
15485                    app.adjType = "provider";
15486                    app.adjTarget = cpr.name;
15487                }
15488                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15489                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15490                }
15491            }
15492        }
15493
15494        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15495            // A client of one of our services or providers is in the top state.  We
15496            // *may* want to be in the top state, but not if we are already running in
15497            // the background for some other reason.  For the decision here, we are going
15498            // to pick out a few specific states that we want to remain in when a client
15499            // is top (states that tend to be longer-term) and otherwise allow it to go
15500            // to the top state.
15501            switch (procState) {
15502                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15503                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15504                case ActivityManager.PROCESS_STATE_SERVICE:
15505                    // These all are longer-term states, so pull them up to the top
15506                    // of the background states, but not all the way to the top state.
15507                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15508                    break;
15509                default:
15510                    // Otherwise, top is a better choice, so take it.
15511                    procState = ActivityManager.PROCESS_STATE_TOP;
15512                    break;
15513            }
15514        }
15515
15516        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15517            if (app.hasClientActivities) {
15518                // This is a cached process, but with client activities.  Mark it so.
15519                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15520                app.adjType = "cch-client-act";
15521            } else if (app.treatLikeActivity) {
15522                // This is a cached process, but somebody wants us to treat it like it has
15523                // an activity, okay!
15524                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15525                app.adjType = "cch-as-act";
15526            }
15527        }
15528
15529        if (adj == ProcessList.SERVICE_ADJ) {
15530            if (doingAll) {
15531                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15532                mNewNumServiceProcs++;
15533                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15534                if (!app.serviceb) {
15535                    // This service isn't far enough down on the LRU list to
15536                    // normally be a B service, but if we are low on RAM and it
15537                    // is large we want to force it down since we would prefer to
15538                    // keep launcher over it.
15539                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15540                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15541                        app.serviceHighRam = true;
15542                        app.serviceb = true;
15543                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15544                    } else {
15545                        mNewNumAServiceProcs++;
15546                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15547                    }
15548                } else {
15549                    app.serviceHighRam = false;
15550                }
15551            }
15552            if (app.serviceb) {
15553                adj = ProcessList.SERVICE_B_ADJ;
15554            }
15555        }
15556
15557        app.curRawAdj = adj;
15558
15559        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15560        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15561        if (adj > app.maxAdj) {
15562            adj = app.maxAdj;
15563            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15564                schedGroup = Process.THREAD_GROUP_DEFAULT;
15565            }
15566        }
15567        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15568            app.keeping = true;
15569        }
15570
15571        // Do final modification to adj.  Everything we do between here and applying
15572        // the final setAdj must be done in this function, because we will also use
15573        // it when computing the final cached adj later.  Note that we don't need to
15574        // worry about this for max adj above, since max adj will always be used to
15575        // keep it out of the cached vaues.
15576        app.curAdj = app.modifyRawOomAdj(adj);
15577        app.curSchedGroup = schedGroup;
15578        app.curProcState = procState;
15579        app.foregroundActivities = foregroundActivities;
15580
15581        return app.curRawAdj;
15582    }
15583
15584    /**
15585     * Schedule PSS collection of a process.
15586     */
15587    void requestPssLocked(ProcessRecord proc, int procState) {
15588        if (mPendingPssProcesses.contains(proc)) {
15589            return;
15590        }
15591        if (mPendingPssProcesses.size() == 0) {
15592            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15593        }
15594        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15595        proc.pssProcState = procState;
15596        mPendingPssProcesses.add(proc);
15597    }
15598
15599    /**
15600     * Schedule PSS collection of all processes.
15601     */
15602    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15603        if (!always) {
15604            if (now < (mLastFullPssTime +
15605                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15606                return;
15607            }
15608        }
15609        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15610        mLastFullPssTime = now;
15611        mFullPssPending = true;
15612        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15613        mPendingPssProcesses.clear();
15614        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15615            ProcessRecord app = mLruProcesses.get(i);
15616            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15617                app.pssProcState = app.setProcState;
15618                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15619                        isSleeping(), now);
15620                mPendingPssProcesses.add(app);
15621            }
15622        }
15623        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15624    }
15625
15626    /**
15627     * Ask a given process to GC right now.
15628     */
15629    final void performAppGcLocked(ProcessRecord app) {
15630        try {
15631            app.lastRequestedGc = SystemClock.uptimeMillis();
15632            if (app.thread != null) {
15633                if (app.reportLowMemory) {
15634                    app.reportLowMemory = false;
15635                    app.thread.scheduleLowMemory();
15636                } else {
15637                    app.thread.processInBackground();
15638                }
15639            }
15640        } catch (Exception e) {
15641            // whatever.
15642        }
15643    }
15644
15645    /**
15646     * Returns true if things are idle enough to perform GCs.
15647     */
15648    private final boolean canGcNowLocked() {
15649        boolean processingBroadcasts = false;
15650        for (BroadcastQueue q : mBroadcastQueues) {
15651            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15652                processingBroadcasts = true;
15653            }
15654        }
15655        return !processingBroadcasts
15656                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15657    }
15658
15659    /**
15660     * Perform GCs on all processes that are waiting for it, but only
15661     * if things are idle.
15662     */
15663    final void performAppGcsLocked() {
15664        final int N = mProcessesToGc.size();
15665        if (N <= 0) {
15666            return;
15667        }
15668        if (canGcNowLocked()) {
15669            while (mProcessesToGc.size() > 0) {
15670                ProcessRecord proc = mProcessesToGc.remove(0);
15671                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15672                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15673                            <= SystemClock.uptimeMillis()) {
15674                        // To avoid spamming the system, we will GC processes one
15675                        // at a time, waiting a few seconds between each.
15676                        performAppGcLocked(proc);
15677                        scheduleAppGcsLocked();
15678                        return;
15679                    } else {
15680                        // It hasn't been long enough since we last GCed this
15681                        // process...  put it in the list to wait for its time.
15682                        addProcessToGcListLocked(proc);
15683                        break;
15684                    }
15685                }
15686            }
15687
15688            scheduleAppGcsLocked();
15689        }
15690    }
15691
15692    /**
15693     * If all looks good, perform GCs on all processes waiting for them.
15694     */
15695    final void performAppGcsIfAppropriateLocked() {
15696        if (canGcNowLocked()) {
15697            performAppGcsLocked();
15698            return;
15699        }
15700        // Still not idle, wait some more.
15701        scheduleAppGcsLocked();
15702    }
15703
15704    /**
15705     * Schedule the execution of all pending app GCs.
15706     */
15707    final void scheduleAppGcsLocked() {
15708        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15709
15710        if (mProcessesToGc.size() > 0) {
15711            // Schedule a GC for the time to the next process.
15712            ProcessRecord proc = mProcessesToGc.get(0);
15713            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15714
15715            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15716            long now = SystemClock.uptimeMillis();
15717            if (when < (now+GC_TIMEOUT)) {
15718                when = now + GC_TIMEOUT;
15719            }
15720            mHandler.sendMessageAtTime(msg, when);
15721        }
15722    }
15723
15724    /**
15725     * Add a process to the array of processes waiting to be GCed.  Keeps the
15726     * list in sorted order by the last GC time.  The process can't already be
15727     * on the list.
15728     */
15729    final void addProcessToGcListLocked(ProcessRecord proc) {
15730        boolean added = false;
15731        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15732            if (mProcessesToGc.get(i).lastRequestedGc <
15733                    proc.lastRequestedGc) {
15734                added = true;
15735                mProcessesToGc.add(i+1, proc);
15736                break;
15737            }
15738        }
15739        if (!added) {
15740            mProcessesToGc.add(0, proc);
15741        }
15742    }
15743
15744    /**
15745     * Set up to ask a process to GC itself.  This will either do it
15746     * immediately, or put it on the list of processes to gc the next
15747     * time things are idle.
15748     */
15749    final void scheduleAppGcLocked(ProcessRecord app) {
15750        long now = SystemClock.uptimeMillis();
15751        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15752            return;
15753        }
15754        if (!mProcessesToGc.contains(app)) {
15755            addProcessToGcListLocked(app);
15756            scheduleAppGcsLocked();
15757        }
15758    }
15759
15760    final void checkExcessivePowerUsageLocked(boolean doKills) {
15761        updateCpuStatsNow();
15762
15763        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15764        boolean doWakeKills = doKills;
15765        boolean doCpuKills = doKills;
15766        if (mLastPowerCheckRealtime == 0) {
15767            doWakeKills = false;
15768        }
15769        if (mLastPowerCheckUptime == 0) {
15770            doCpuKills = false;
15771        }
15772        if (stats.isScreenOn()) {
15773            doWakeKills = false;
15774        }
15775        final long curRealtime = SystemClock.elapsedRealtime();
15776        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15777        final long curUptime = SystemClock.uptimeMillis();
15778        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15779        mLastPowerCheckRealtime = curRealtime;
15780        mLastPowerCheckUptime = curUptime;
15781        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15782            doWakeKills = false;
15783        }
15784        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15785            doCpuKills = false;
15786        }
15787        int i = mLruProcesses.size();
15788        while (i > 0) {
15789            i--;
15790            ProcessRecord app = mLruProcesses.get(i);
15791            if (!app.keeping) {
15792                long wtime;
15793                synchronized (stats) {
15794                    wtime = stats.getProcessWakeTime(app.info.uid,
15795                            app.pid, curRealtime);
15796                }
15797                long wtimeUsed = wtime - app.lastWakeTime;
15798                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15799                if (DEBUG_POWER) {
15800                    StringBuilder sb = new StringBuilder(128);
15801                    sb.append("Wake for ");
15802                    app.toShortString(sb);
15803                    sb.append(": over ");
15804                    TimeUtils.formatDuration(realtimeSince, sb);
15805                    sb.append(" used ");
15806                    TimeUtils.formatDuration(wtimeUsed, sb);
15807                    sb.append(" (");
15808                    sb.append((wtimeUsed*100)/realtimeSince);
15809                    sb.append("%)");
15810                    Slog.i(TAG, sb.toString());
15811                    sb.setLength(0);
15812                    sb.append("CPU for ");
15813                    app.toShortString(sb);
15814                    sb.append(": over ");
15815                    TimeUtils.formatDuration(uptimeSince, sb);
15816                    sb.append(" used ");
15817                    TimeUtils.formatDuration(cputimeUsed, sb);
15818                    sb.append(" (");
15819                    sb.append((cputimeUsed*100)/uptimeSince);
15820                    sb.append("%)");
15821                    Slog.i(TAG, sb.toString());
15822                }
15823                // If a process has held a wake lock for more
15824                // than 50% of the time during this period,
15825                // that sounds bad.  Kill!
15826                if (doWakeKills && realtimeSince > 0
15827                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15828                    synchronized (stats) {
15829                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15830                                realtimeSince, wtimeUsed);
15831                    }
15832                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15833                            + " during " + realtimeSince);
15834                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15835                } else if (doCpuKills && uptimeSince > 0
15836                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15837                    synchronized (stats) {
15838                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15839                                uptimeSince, cputimeUsed);
15840                    }
15841                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15842                            + " during " + uptimeSince);
15843                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15844                } else {
15845                    app.lastWakeTime = wtime;
15846                    app.lastCpuTime = app.curCpuTime;
15847                }
15848            }
15849        }
15850    }
15851
15852    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15853            ProcessRecord TOP_APP, boolean doingAll, long now) {
15854        boolean success = true;
15855
15856        if (app.curRawAdj != app.setRawAdj) {
15857            if (wasKeeping && !app.keeping) {
15858                // This app is no longer something we want to keep.  Note
15859                // its current wake lock time to later know to kill it if
15860                // it is not behaving well.
15861                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15862                synchronized (stats) {
15863                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15864                            app.pid, SystemClock.elapsedRealtime());
15865                }
15866                app.lastCpuTime = app.curCpuTime;
15867            }
15868
15869            app.setRawAdj = app.curRawAdj;
15870        }
15871
15872        int changes = 0;
15873
15874        if (app.curAdj != app.setAdj) {
15875            ProcessList.setOomAdj(app.pid, app.curAdj);
15876            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15877                TAG, "Set " + app.pid + " " + app.processName +
15878                " adj " + app.curAdj + ": " + app.adjType);
15879            app.setAdj = app.curAdj;
15880        }
15881
15882        if (app.setSchedGroup != app.curSchedGroup) {
15883            app.setSchedGroup = app.curSchedGroup;
15884            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15885                    "Setting process group of " + app.processName
15886                    + " to " + app.curSchedGroup);
15887            if (app.waitingToKill != null &&
15888                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15889                killUnneededProcessLocked(app, app.waitingToKill);
15890                success = false;
15891            } else {
15892                if (true) {
15893                    long oldId = Binder.clearCallingIdentity();
15894                    try {
15895                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15896                    } catch (Exception e) {
15897                        Slog.w(TAG, "Failed setting process group of " + app.pid
15898                                + " to " + app.curSchedGroup);
15899                        e.printStackTrace();
15900                    } finally {
15901                        Binder.restoreCallingIdentity(oldId);
15902                    }
15903                } else {
15904                    if (app.thread != null) {
15905                        try {
15906                            app.thread.setSchedulingGroup(app.curSchedGroup);
15907                        } catch (RemoteException e) {
15908                        }
15909                    }
15910                }
15911                Process.setSwappiness(app.pid,
15912                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15913            }
15914        }
15915        if (app.repForegroundActivities != app.foregroundActivities) {
15916            app.repForegroundActivities = app.foregroundActivities;
15917            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15918        }
15919        if (app.repProcState != app.curProcState) {
15920            app.repProcState = app.curProcState;
15921            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15922            if (app.thread != null) {
15923                try {
15924                    if (false) {
15925                        //RuntimeException h = new RuntimeException("here");
15926                        Slog.i(TAG, "Sending new process state " + app.repProcState
15927                                + " to " + app /*, h*/);
15928                    }
15929                    app.thread.setProcessState(app.repProcState);
15930                } catch (RemoteException e) {
15931                }
15932            }
15933        }
15934        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15935                app.setProcState)) {
15936            app.lastStateTime = now;
15937            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15938                    isSleeping(), now);
15939            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15940                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15941                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15942                    + (app.nextPssTime-now) + ": " + app);
15943        } else {
15944            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15945                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15946                requestPssLocked(app, app.setProcState);
15947                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15948                        isSleeping(), now);
15949            } else if (false && DEBUG_PSS) {
15950                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15951            }
15952        }
15953        if (app.setProcState != app.curProcState) {
15954            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15955                    "Proc state change of " + app.processName
15956                    + " to " + app.curProcState);
15957            app.setProcState = app.curProcState;
15958            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15959                app.notCachedSinceIdle = false;
15960            }
15961            if (!doingAll) {
15962                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15963            } else {
15964                app.procStateChanged = true;
15965            }
15966        }
15967
15968        if (changes != 0) {
15969            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15970            int i = mPendingProcessChanges.size()-1;
15971            ProcessChangeItem item = null;
15972            while (i >= 0) {
15973                item = mPendingProcessChanges.get(i);
15974                if (item.pid == app.pid) {
15975                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15976                    break;
15977                }
15978                i--;
15979            }
15980            if (i < 0) {
15981                // No existing item in pending changes; need a new one.
15982                final int NA = mAvailProcessChanges.size();
15983                if (NA > 0) {
15984                    item = mAvailProcessChanges.remove(NA-1);
15985                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15986                } else {
15987                    item = new ProcessChangeItem();
15988                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15989                }
15990                item.changes = 0;
15991                item.pid = app.pid;
15992                item.uid = app.info.uid;
15993                if (mPendingProcessChanges.size() == 0) {
15994                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15995                            "*** Enqueueing dispatch processes changed!");
15996                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15997                }
15998                mPendingProcessChanges.add(item);
15999            }
16000            item.changes |= changes;
16001            item.processState = app.repProcState;
16002            item.foregroundActivities = app.repForegroundActivities;
16003            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16004                    + Integer.toHexString(System.identityHashCode(item))
16005                    + " " + app.toShortString() + ": changes=" + item.changes
16006                    + " procState=" + item.processState
16007                    + " foreground=" + item.foregroundActivities
16008                    + " type=" + app.adjType + " source=" + app.adjSource
16009                    + " target=" + app.adjTarget);
16010        }
16011
16012        return success;
16013    }
16014
16015    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16016        if (proc.thread != null && proc.baseProcessTracker != null) {
16017            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16018        }
16019    }
16020
16021    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16022            ProcessRecord TOP_APP, boolean doingAll, long now) {
16023        if (app.thread == null) {
16024            return false;
16025        }
16026
16027        final boolean wasKeeping = app.keeping;
16028
16029        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16030
16031        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16032    }
16033
16034    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16035            boolean oomAdj) {
16036        if (isForeground != proc.foregroundServices) {
16037            proc.foregroundServices = isForeground;
16038            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16039                    proc.info.uid);
16040            if (isForeground) {
16041                if (curProcs == null) {
16042                    curProcs = new ArrayList<ProcessRecord>();
16043                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16044                }
16045                if (!curProcs.contains(proc)) {
16046                    curProcs.add(proc);
16047                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16048                            proc.info.packageName, proc.info.uid);
16049                }
16050            } else {
16051                if (curProcs != null) {
16052                    if (curProcs.remove(proc)) {
16053                        mBatteryStatsService.noteEvent(
16054                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16055                                proc.info.packageName, proc.info.uid);
16056                        if (curProcs.size() <= 0) {
16057                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16058                        }
16059                    }
16060                }
16061            }
16062            if (oomAdj) {
16063                updateOomAdjLocked();
16064            }
16065        }
16066    }
16067
16068    private final ActivityRecord resumedAppLocked() {
16069        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16070        String pkg;
16071        int uid;
16072        if (act != null && !act.sleeping) {
16073            pkg = act.packageName;
16074            uid = act.info.applicationInfo.uid;
16075        } else {
16076            pkg = null;
16077            uid = -1;
16078        }
16079        // Has the UID or resumed package name changed?
16080        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16081                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16082            if (mCurResumedPackage != null) {
16083                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16084                        mCurResumedPackage, mCurResumedUid);
16085            }
16086            mCurResumedPackage = pkg;
16087            mCurResumedUid = uid;
16088            if (mCurResumedPackage != null) {
16089                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16090                        mCurResumedPackage, mCurResumedUid);
16091            }
16092        }
16093        return act;
16094    }
16095
16096    final boolean updateOomAdjLocked(ProcessRecord app) {
16097        final ActivityRecord TOP_ACT = resumedAppLocked();
16098        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16099        final boolean wasCached = app.cached;
16100
16101        mAdjSeq++;
16102
16103        // This is the desired cached adjusment we want to tell it to use.
16104        // If our app is currently cached, we know it, and that is it.  Otherwise,
16105        // we don't know it yet, and it needs to now be cached we will then
16106        // need to do a complete oom adj.
16107        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16108                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16109        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16110                SystemClock.uptimeMillis());
16111        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16112            // Changed to/from cached state, so apps after it in the LRU
16113            // list may also be changed.
16114            updateOomAdjLocked();
16115        }
16116        return success;
16117    }
16118
16119    final void updateOomAdjLocked() {
16120        final ActivityRecord TOP_ACT = resumedAppLocked();
16121        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16122        final long now = SystemClock.uptimeMillis();
16123        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16124        final int N = mLruProcesses.size();
16125
16126        if (false) {
16127            RuntimeException e = new RuntimeException();
16128            e.fillInStackTrace();
16129            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16130        }
16131
16132        mAdjSeq++;
16133        mNewNumServiceProcs = 0;
16134        mNewNumAServiceProcs = 0;
16135
16136        final int emptyProcessLimit;
16137        final int cachedProcessLimit;
16138        if (mProcessLimit <= 0) {
16139            emptyProcessLimit = cachedProcessLimit = 0;
16140        } else if (mProcessLimit == 1) {
16141            emptyProcessLimit = 1;
16142            cachedProcessLimit = 0;
16143        } else {
16144            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16145            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16146        }
16147
16148        // Let's determine how many processes we have running vs.
16149        // how many slots we have for background processes; we may want
16150        // to put multiple processes in a slot of there are enough of
16151        // them.
16152        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16153                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16154        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16155        if (numEmptyProcs > cachedProcessLimit) {
16156            // If there are more empty processes than our limit on cached
16157            // processes, then use the cached process limit for the factor.
16158            // This ensures that the really old empty processes get pushed
16159            // down to the bottom, so if we are running low on memory we will
16160            // have a better chance at keeping around more cached processes
16161            // instead of a gazillion empty processes.
16162            numEmptyProcs = cachedProcessLimit;
16163        }
16164        int emptyFactor = numEmptyProcs/numSlots;
16165        if (emptyFactor < 1) emptyFactor = 1;
16166        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16167        if (cachedFactor < 1) cachedFactor = 1;
16168        int stepCached = 0;
16169        int stepEmpty = 0;
16170        int numCached = 0;
16171        int numEmpty = 0;
16172        int numTrimming = 0;
16173
16174        mNumNonCachedProcs = 0;
16175        mNumCachedHiddenProcs = 0;
16176
16177        // First update the OOM adjustment for each of the
16178        // application processes based on their current state.
16179        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16180        int nextCachedAdj = curCachedAdj+1;
16181        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16182        int nextEmptyAdj = curEmptyAdj+2;
16183        for (int i=N-1; i>=0; i--) {
16184            ProcessRecord app = mLruProcesses.get(i);
16185            if (!app.killedByAm && app.thread != null) {
16186                app.procStateChanged = false;
16187                final boolean wasKeeping = app.keeping;
16188                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16189
16190                // If we haven't yet assigned the final cached adj
16191                // to the process, do that now.
16192                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16193                    switch (app.curProcState) {
16194                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16195                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16196                            // This process is a cached process holding activities...
16197                            // assign it the next cached value for that type, and then
16198                            // step that cached level.
16199                            app.curRawAdj = curCachedAdj;
16200                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16201                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16202                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16203                                    + ")");
16204                            if (curCachedAdj != nextCachedAdj) {
16205                                stepCached++;
16206                                if (stepCached >= cachedFactor) {
16207                                    stepCached = 0;
16208                                    curCachedAdj = nextCachedAdj;
16209                                    nextCachedAdj += 2;
16210                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16211                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16212                                    }
16213                                }
16214                            }
16215                            break;
16216                        default:
16217                            // For everything else, assign next empty cached process
16218                            // level and bump that up.  Note that this means that
16219                            // long-running services that have dropped down to the
16220                            // cached level will be treated as empty (since their process
16221                            // state is still as a service), which is what we want.
16222                            app.curRawAdj = curEmptyAdj;
16223                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16224                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16225                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16226                                    + ")");
16227                            if (curEmptyAdj != nextEmptyAdj) {
16228                                stepEmpty++;
16229                                if (stepEmpty >= emptyFactor) {
16230                                    stepEmpty = 0;
16231                                    curEmptyAdj = nextEmptyAdj;
16232                                    nextEmptyAdj += 2;
16233                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16234                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16235                                    }
16236                                }
16237                            }
16238                            break;
16239                    }
16240                }
16241
16242                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16243
16244                // Count the number of process types.
16245                switch (app.curProcState) {
16246                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16247                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16248                        mNumCachedHiddenProcs++;
16249                        numCached++;
16250                        if (numCached > cachedProcessLimit) {
16251                            killUnneededProcessLocked(app, "cached #" + numCached);
16252                        }
16253                        break;
16254                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16255                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16256                                && app.lastActivityTime < oldTime) {
16257                            killUnneededProcessLocked(app, "empty for "
16258                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16259                                    / 1000) + "s");
16260                        } else {
16261                            numEmpty++;
16262                            if (numEmpty > emptyProcessLimit) {
16263                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16264                            }
16265                        }
16266                        break;
16267                    default:
16268                        mNumNonCachedProcs++;
16269                        break;
16270                }
16271
16272                if (app.isolated && app.services.size() <= 0) {
16273                    // If this is an isolated process, and there are no
16274                    // services running in it, then the process is no longer
16275                    // needed.  We agressively kill these because we can by
16276                    // definition not re-use the same process again, and it is
16277                    // good to avoid having whatever code was running in them
16278                    // left sitting around after no longer needed.
16279                    killUnneededProcessLocked(app, "isolated not needed");
16280                }
16281
16282                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16283                        && !app.killedByAm) {
16284                    numTrimming++;
16285                }
16286            }
16287        }
16288
16289        mNumServiceProcs = mNewNumServiceProcs;
16290
16291        // Now determine the memory trimming level of background processes.
16292        // Unfortunately we need to start at the back of the list to do this
16293        // properly.  We only do this if the number of background apps we
16294        // are managing to keep around is less than half the maximum we desire;
16295        // if we are keeping a good number around, we'll let them use whatever
16296        // memory they want.
16297        final int numCachedAndEmpty = numCached + numEmpty;
16298        int memFactor;
16299        if (numCached <= ProcessList.TRIM_CACHED_APPS
16300                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16301            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16302                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16303            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16304                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16305            } else {
16306                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16307            }
16308        } else {
16309            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16310        }
16311        // We always allow the memory level to go up (better).  We only allow it to go
16312        // down if we are in a state where that is allowed, *and* the total number of processes
16313        // has gone down since last time.
16314        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16315                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16316                + " last=" + mLastNumProcesses);
16317        if (memFactor > mLastMemoryLevel) {
16318            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16319                memFactor = mLastMemoryLevel;
16320                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16321            }
16322        }
16323        mLastMemoryLevel = memFactor;
16324        mLastNumProcesses = mLruProcesses.size();
16325        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16326        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16327        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16328            if (mLowRamStartTime == 0) {
16329                mLowRamStartTime = now;
16330            }
16331            int step = 0;
16332            int fgTrimLevel;
16333            switch (memFactor) {
16334                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16335                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16336                    break;
16337                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16338                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16339                    break;
16340                default:
16341                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16342                    break;
16343            }
16344            int factor = numTrimming/3;
16345            int minFactor = 2;
16346            if (mHomeProcess != null) minFactor++;
16347            if (mPreviousProcess != null) minFactor++;
16348            if (factor < minFactor) factor = minFactor;
16349            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16350            for (int i=N-1; i>=0; i--) {
16351                ProcessRecord app = mLruProcesses.get(i);
16352                if (allChanged || app.procStateChanged) {
16353                    setProcessTrackerState(app, trackerMemFactor, now);
16354                    app.procStateChanged = false;
16355                }
16356                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16357                        && !app.killedByAm) {
16358                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16359                        try {
16360                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16361                                    "Trimming memory of " + app.processName
16362                                    + " to " + curLevel);
16363                            app.thread.scheduleTrimMemory(curLevel);
16364                        } catch (RemoteException e) {
16365                        }
16366                        if (false) {
16367                            // For now we won't do this; our memory trimming seems
16368                            // to be good enough at this point that destroying
16369                            // activities causes more harm than good.
16370                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16371                                    && app != mHomeProcess && app != mPreviousProcess) {
16372                                // Need to do this on its own message because the stack may not
16373                                // be in a consistent state at this point.
16374                                // For these apps we will also finish their activities
16375                                // to help them free memory.
16376                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16377                            }
16378                        }
16379                    }
16380                    app.trimMemoryLevel = curLevel;
16381                    step++;
16382                    if (step >= factor) {
16383                        step = 0;
16384                        switch (curLevel) {
16385                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16386                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16387                                break;
16388                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16389                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16390                                break;
16391                        }
16392                    }
16393                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16394                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16395                            && app.thread != null) {
16396                        try {
16397                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16398                                    "Trimming memory of heavy-weight " + app.processName
16399                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16400                            app.thread.scheduleTrimMemory(
16401                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16402                        } catch (RemoteException e) {
16403                        }
16404                    }
16405                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16406                } else {
16407                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16408                            || app.systemNoUi) && app.pendingUiClean) {
16409                        // If this application is now in the background and it
16410                        // had done UI, then give it the special trim level to
16411                        // have it free UI resources.
16412                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16413                        if (app.trimMemoryLevel < level && app.thread != null) {
16414                            try {
16415                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16416                                        "Trimming memory of bg-ui " + app.processName
16417                                        + " to " + level);
16418                                app.thread.scheduleTrimMemory(level);
16419                            } catch (RemoteException e) {
16420                            }
16421                        }
16422                        app.pendingUiClean = false;
16423                    }
16424                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16425                        try {
16426                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16427                                    "Trimming memory of fg " + app.processName
16428                                    + " to " + fgTrimLevel);
16429                            app.thread.scheduleTrimMemory(fgTrimLevel);
16430                        } catch (RemoteException e) {
16431                        }
16432                    }
16433                    app.trimMemoryLevel = fgTrimLevel;
16434                }
16435            }
16436        } else {
16437            if (mLowRamStartTime != 0) {
16438                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16439                mLowRamStartTime = 0;
16440            }
16441            for (int i=N-1; i>=0; i--) {
16442                ProcessRecord app = mLruProcesses.get(i);
16443                if (allChanged || app.procStateChanged) {
16444                    setProcessTrackerState(app, trackerMemFactor, now);
16445                    app.procStateChanged = false;
16446                }
16447                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16448                        || app.systemNoUi) && app.pendingUiClean) {
16449                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16450                            && app.thread != null) {
16451                        try {
16452                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16453                                    "Trimming memory of ui hidden " + app.processName
16454                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16455                            app.thread.scheduleTrimMemory(
16456                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16457                        } catch (RemoteException e) {
16458                        }
16459                    }
16460                    app.pendingUiClean = false;
16461                }
16462                app.trimMemoryLevel = 0;
16463            }
16464        }
16465
16466        if (mAlwaysFinishActivities) {
16467            // Need to do this on its own message because the stack may not
16468            // be in a consistent state at this point.
16469            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16470        }
16471
16472        if (allChanged) {
16473            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16474        }
16475
16476        if (mProcessStats.shouldWriteNowLocked(now)) {
16477            mHandler.post(new Runnable() {
16478                @Override public void run() {
16479                    synchronized (ActivityManagerService.this) {
16480                        mProcessStats.writeStateAsyncLocked();
16481                    }
16482                }
16483            });
16484        }
16485
16486        if (DEBUG_OOM_ADJ) {
16487            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16488        }
16489    }
16490
16491    final void trimApplications() {
16492        synchronized (this) {
16493            int i;
16494
16495            // First remove any unused application processes whose package
16496            // has been removed.
16497            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16498                final ProcessRecord app = mRemovedProcesses.get(i);
16499                if (app.activities.size() == 0
16500                        && app.curReceiver == null && app.services.size() == 0) {
16501                    Slog.i(
16502                        TAG, "Exiting empty application process "
16503                        + app.processName + " ("
16504                        + (app.thread != null ? app.thread.asBinder() : null)
16505                        + ")\n");
16506                    if (app.pid > 0 && app.pid != MY_PID) {
16507                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16508                                app.processName, app.setAdj, "empty");
16509                        app.killedByAm = true;
16510                        Process.killProcessQuiet(app.pid);
16511                    } else {
16512                        try {
16513                            app.thread.scheduleExit();
16514                        } catch (Exception e) {
16515                            // Ignore exceptions.
16516                        }
16517                    }
16518                    cleanUpApplicationRecordLocked(app, false, true, -1);
16519                    mRemovedProcesses.remove(i);
16520
16521                    if (app.persistent) {
16522                        if (app.persistent) {
16523                            addAppLocked(app.info, false, null /* ABI override */);
16524                        }
16525                    }
16526                }
16527            }
16528
16529            // Now update the oom adj for all processes.
16530            updateOomAdjLocked();
16531        }
16532    }
16533
16534    /** This method sends the specified signal to each of the persistent apps */
16535    public void signalPersistentProcesses(int sig) throws RemoteException {
16536        if (sig != Process.SIGNAL_USR1) {
16537            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16538        }
16539
16540        synchronized (this) {
16541            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16542                    != PackageManager.PERMISSION_GRANTED) {
16543                throw new SecurityException("Requires permission "
16544                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16545            }
16546
16547            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16548                ProcessRecord r = mLruProcesses.get(i);
16549                if (r.thread != null && r.persistent) {
16550                    Process.sendSignal(r.pid, sig);
16551                }
16552            }
16553        }
16554    }
16555
16556    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16557        if (proc == null || proc == mProfileProc) {
16558            proc = mProfileProc;
16559            path = mProfileFile;
16560            profileType = mProfileType;
16561            clearProfilerLocked();
16562        }
16563        if (proc == null) {
16564            return;
16565        }
16566        try {
16567            proc.thread.profilerControl(false, path, null, profileType);
16568        } catch (RemoteException e) {
16569            throw new IllegalStateException("Process disappeared");
16570        }
16571    }
16572
16573    private void clearProfilerLocked() {
16574        if (mProfileFd != null) {
16575            try {
16576                mProfileFd.close();
16577            } catch (IOException e) {
16578            }
16579        }
16580        mProfileApp = null;
16581        mProfileProc = null;
16582        mProfileFile = null;
16583        mProfileType = 0;
16584        mAutoStopProfiler = false;
16585    }
16586
16587    public boolean profileControl(String process, int userId, boolean start,
16588            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16589
16590        try {
16591            synchronized (this) {
16592                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16593                // its own permission.
16594                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16595                        != PackageManager.PERMISSION_GRANTED) {
16596                    throw new SecurityException("Requires permission "
16597                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16598                }
16599
16600                if (start && fd == null) {
16601                    throw new IllegalArgumentException("null fd");
16602                }
16603
16604                ProcessRecord proc = null;
16605                if (process != null) {
16606                    proc = findProcessLocked(process, userId, "profileControl");
16607                }
16608
16609                if (start && (proc == null || proc.thread == null)) {
16610                    throw new IllegalArgumentException("Unknown process: " + process);
16611                }
16612
16613                if (start) {
16614                    stopProfilerLocked(null, null, 0);
16615                    setProfileApp(proc.info, proc.processName, path, fd, false);
16616                    mProfileProc = proc;
16617                    mProfileType = profileType;
16618                    try {
16619                        fd = fd.dup();
16620                    } catch (IOException e) {
16621                        fd = null;
16622                    }
16623                    proc.thread.profilerControl(start, path, fd, profileType);
16624                    fd = null;
16625                    mProfileFd = null;
16626                } else {
16627                    stopProfilerLocked(proc, path, profileType);
16628                    if (fd != null) {
16629                        try {
16630                            fd.close();
16631                        } catch (IOException e) {
16632                        }
16633                    }
16634                }
16635
16636                return true;
16637            }
16638        } catch (RemoteException e) {
16639            throw new IllegalStateException("Process disappeared");
16640        } finally {
16641            if (fd != null) {
16642                try {
16643                    fd.close();
16644                } catch (IOException e) {
16645                }
16646            }
16647        }
16648    }
16649
16650    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16651        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16652                userId, true, true, callName, null);
16653        ProcessRecord proc = null;
16654        try {
16655            int pid = Integer.parseInt(process);
16656            synchronized (mPidsSelfLocked) {
16657                proc = mPidsSelfLocked.get(pid);
16658            }
16659        } catch (NumberFormatException e) {
16660        }
16661
16662        if (proc == null) {
16663            ArrayMap<String, SparseArray<ProcessRecord>> all
16664                    = mProcessNames.getMap();
16665            SparseArray<ProcessRecord> procs = all.get(process);
16666            if (procs != null && procs.size() > 0) {
16667                proc = procs.valueAt(0);
16668                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16669                    for (int i=1; i<procs.size(); i++) {
16670                        ProcessRecord thisProc = procs.valueAt(i);
16671                        if (thisProc.userId == userId) {
16672                            proc = thisProc;
16673                            break;
16674                        }
16675                    }
16676                }
16677            }
16678        }
16679
16680        return proc;
16681    }
16682
16683    public boolean dumpHeap(String process, int userId, boolean managed,
16684            String path, ParcelFileDescriptor fd) throws RemoteException {
16685
16686        try {
16687            synchronized (this) {
16688                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16689                // its own permission (same as profileControl).
16690                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16691                        != PackageManager.PERMISSION_GRANTED) {
16692                    throw new SecurityException("Requires permission "
16693                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16694                }
16695
16696                if (fd == null) {
16697                    throw new IllegalArgumentException("null fd");
16698                }
16699
16700                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16701                if (proc == null || proc.thread == null) {
16702                    throw new IllegalArgumentException("Unknown process: " + process);
16703                }
16704
16705                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16706                if (!isDebuggable) {
16707                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16708                        throw new SecurityException("Process not debuggable: " + proc);
16709                    }
16710                }
16711
16712                proc.thread.dumpHeap(managed, path, fd);
16713                fd = null;
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    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16729    public void monitor() {
16730        synchronized (this) { }
16731    }
16732
16733    void onCoreSettingsChange(Bundle settings) {
16734        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16735            ProcessRecord processRecord = mLruProcesses.get(i);
16736            try {
16737                if (processRecord.thread != null) {
16738                    processRecord.thread.setCoreSettings(settings);
16739                }
16740            } catch (RemoteException re) {
16741                /* ignore */
16742            }
16743        }
16744    }
16745
16746    // Multi-user methods
16747
16748    /**
16749     * Start user, if its not already running, but don't bring it to foreground.
16750     */
16751    @Override
16752    public boolean startUserInBackground(final int userId) {
16753        return startUser(userId, /* foreground */ false);
16754    }
16755
16756    /**
16757     * Refreshes the list of users related to the current user when either a
16758     * user switch happens or when a new related user is started in the
16759     * background.
16760     */
16761    private void updateCurrentProfileIdsLocked() {
16762        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16763                mCurrentUserId, false /* enabledOnly */);
16764        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16765        for (int i = 0; i < currentProfileIds.length; i++) {
16766            currentProfileIds[i] = profiles.get(i).id;
16767        }
16768        mCurrentProfileIds = currentProfileIds;
16769    }
16770
16771    private Set getProfileIdsLocked(int userId) {
16772        Set userIds = new HashSet<Integer>();
16773        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16774                userId, false /* enabledOnly */);
16775        for (UserInfo user : profiles) {
16776            userIds.add(Integer.valueOf(user.id));
16777        }
16778        return userIds;
16779    }
16780
16781    @Override
16782    public boolean switchUser(final int userId) {
16783        return startUser(userId, /* foregound */ true);
16784    }
16785
16786    private boolean startUser(final int userId, boolean foreground) {
16787        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16788                != PackageManager.PERMISSION_GRANTED) {
16789            String msg = "Permission Denial: switchUser() from pid="
16790                    + Binder.getCallingPid()
16791                    + ", uid=" + Binder.getCallingUid()
16792                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16793            Slog.w(TAG, msg);
16794            throw new SecurityException(msg);
16795        }
16796
16797        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16798
16799        final long ident = Binder.clearCallingIdentity();
16800        try {
16801            synchronized (this) {
16802                final int oldUserId = mCurrentUserId;
16803                if (oldUserId == userId) {
16804                    return true;
16805                }
16806
16807                mStackSupervisor.setLockTaskModeLocked(null, false);
16808
16809                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16810                if (userInfo == null) {
16811                    Slog.w(TAG, "No user info for user #" + userId);
16812                    return false;
16813                }
16814
16815                if (foreground) {
16816                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16817                            R.anim.screen_user_enter);
16818                }
16819
16820                boolean needStart = false;
16821
16822                // If the user we are switching to is not currently started, then
16823                // we need to start it now.
16824                if (mStartedUsers.get(userId) == null) {
16825                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16826                    updateStartedUserArrayLocked();
16827                    needStart = true;
16828                }
16829
16830                final Integer userIdInt = Integer.valueOf(userId);
16831                mUserLru.remove(userIdInt);
16832                mUserLru.add(userIdInt);
16833
16834                if (foreground) {
16835                    mCurrentUserId = userId;
16836                    updateCurrentProfileIdsLocked();
16837                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16838                    // Once the internal notion of the active user has switched, we lock the device
16839                    // with the option to show the user switcher on the keyguard.
16840                    mWindowManager.lockNow(null);
16841                } else {
16842                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16843                    updateCurrentProfileIdsLocked();
16844                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16845                    mUserLru.remove(currentUserIdInt);
16846                    mUserLru.add(currentUserIdInt);
16847                }
16848
16849                final UserStartedState uss = mStartedUsers.get(userId);
16850
16851                // Make sure user is in the started state.  If it is currently
16852                // stopping, we need to knock that off.
16853                if (uss.mState == UserStartedState.STATE_STOPPING) {
16854                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16855                    // so we can just fairly silently bring the user back from
16856                    // the almost-dead.
16857                    uss.mState = UserStartedState.STATE_RUNNING;
16858                    updateStartedUserArrayLocked();
16859                    needStart = true;
16860                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16861                    // This means ACTION_SHUTDOWN has been sent, so we will
16862                    // need to treat this as a new boot of the user.
16863                    uss.mState = UserStartedState.STATE_BOOTING;
16864                    updateStartedUserArrayLocked();
16865                    needStart = true;
16866                }
16867
16868                if (uss.mState == UserStartedState.STATE_BOOTING) {
16869                    // Booting up a new user, need to tell system services about it.
16870                    // Note that this is on the same handler as scheduling of broadcasts,
16871                    // which is important because it needs to go first.
16872                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16873                }
16874
16875                if (foreground) {
16876                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16877                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16878                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16879                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16880                            oldUserId, userId, uss));
16881                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16882                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16883                }
16884
16885                if (needStart) {
16886                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16887                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16888                            | Intent.FLAG_RECEIVER_FOREGROUND);
16889                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16890                    broadcastIntentLocked(null, null, intent,
16891                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16892                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16893                }
16894
16895                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16896                    if (userId != UserHandle.USER_OWNER) {
16897                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16898                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16899                        broadcastIntentLocked(null, null, intent, null,
16900                                new IIntentReceiver.Stub() {
16901                                    public void performReceive(Intent intent, int resultCode,
16902                                            String data, Bundle extras, boolean ordered,
16903                                            boolean sticky, int sendingUser) {
16904                                        userInitialized(uss, userId);
16905                                    }
16906                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16907                                true, false, MY_PID, Process.SYSTEM_UID,
16908                                userId);
16909                        uss.initializing = true;
16910                    } else {
16911                        getUserManagerLocked().makeInitialized(userInfo.id);
16912                    }
16913                }
16914
16915                if (foreground) {
16916                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16917                    if (homeInFront) {
16918                        startHomeActivityLocked(userId);
16919                    } else {
16920                        mStackSupervisor.resumeTopActivitiesLocked();
16921                    }
16922                    EventLogTags.writeAmSwitchUser(userId);
16923                    getUserManagerLocked().userForeground(userId);
16924                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16925                } else {
16926                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16927                }
16928
16929                if (needStart) {
16930                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16931                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16932                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16933                    broadcastIntentLocked(null, null, intent,
16934                            null, new IIntentReceiver.Stub() {
16935                                @Override
16936                                public void performReceive(Intent intent, int resultCode, String data,
16937                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16938                                        throws RemoteException {
16939                                }
16940                            }, 0, null, null,
16941                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16942                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16943                }
16944            }
16945        } finally {
16946            Binder.restoreCallingIdentity(ident);
16947        }
16948
16949        return true;
16950    }
16951
16952    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16953        long ident = Binder.clearCallingIdentity();
16954        try {
16955            Intent intent;
16956            if (oldUserId >= 0) {
16957                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16958                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16959                        | Intent.FLAG_RECEIVER_FOREGROUND);
16960                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16961                broadcastIntentLocked(null, null, intent,
16962                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16963                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16964            }
16965            if (newUserId >= 0) {
16966                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16967                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16968                        | Intent.FLAG_RECEIVER_FOREGROUND);
16969                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16970                broadcastIntentLocked(null, null, intent,
16971                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16972                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16973                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16974                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16975                        | Intent.FLAG_RECEIVER_FOREGROUND);
16976                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16977                broadcastIntentLocked(null, null, intent,
16978                        null, null, 0, null, null,
16979                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16980                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16981            }
16982        } finally {
16983            Binder.restoreCallingIdentity(ident);
16984        }
16985    }
16986
16987    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16988            final int newUserId) {
16989        final int N = mUserSwitchObservers.beginBroadcast();
16990        if (N > 0) {
16991            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16992                int mCount = 0;
16993                @Override
16994                public void sendResult(Bundle data) throws RemoteException {
16995                    synchronized (ActivityManagerService.this) {
16996                        if (mCurUserSwitchCallback == this) {
16997                            mCount++;
16998                            if (mCount == N) {
16999                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17000                            }
17001                        }
17002                    }
17003                }
17004            };
17005            synchronized (this) {
17006                uss.switching = true;
17007                mCurUserSwitchCallback = callback;
17008            }
17009            for (int i=0; i<N; i++) {
17010                try {
17011                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17012                            newUserId, callback);
17013                } catch (RemoteException e) {
17014                }
17015            }
17016        } else {
17017            synchronized (this) {
17018                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17019            }
17020        }
17021        mUserSwitchObservers.finishBroadcast();
17022    }
17023
17024    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17025        synchronized (this) {
17026            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17027            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17028        }
17029    }
17030
17031    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17032        mCurUserSwitchCallback = null;
17033        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17034        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17035                oldUserId, newUserId, uss));
17036    }
17037
17038    void userInitialized(UserStartedState uss, int newUserId) {
17039        completeSwitchAndInitalize(uss, newUserId, true, false);
17040    }
17041
17042    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17043        completeSwitchAndInitalize(uss, newUserId, false, true);
17044    }
17045
17046    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17047            boolean clearInitializing, boolean clearSwitching) {
17048        boolean unfrozen = false;
17049        synchronized (this) {
17050            if (clearInitializing) {
17051                uss.initializing = false;
17052                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17053            }
17054            if (clearSwitching) {
17055                uss.switching = false;
17056            }
17057            if (!uss.switching && !uss.initializing) {
17058                mWindowManager.stopFreezingScreen();
17059                unfrozen = true;
17060            }
17061        }
17062        if (unfrozen) {
17063            final int N = mUserSwitchObservers.beginBroadcast();
17064            for (int i=0; i<N; i++) {
17065                try {
17066                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17067                } catch (RemoteException e) {
17068                }
17069            }
17070            mUserSwitchObservers.finishBroadcast();
17071        }
17072    }
17073
17074    void scheduleStartProfilesLocked() {
17075        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17076            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17077                    DateUtils.SECOND_IN_MILLIS);
17078        }
17079    }
17080
17081    void startProfilesLocked() {
17082        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17083        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17084                mCurrentUserId, false /* enabledOnly */);
17085        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17086        for (UserInfo user : profiles) {
17087            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17088                    && user.id != mCurrentUserId) {
17089                toStart.add(user);
17090            }
17091        }
17092        final int n = toStart.size();
17093        int i = 0;
17094        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17095            startUserInBackground(toStart.get(i).id);
17096        }
17097        if (i < n) {
17098            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17099        }
17100    }
17101
17102    void finishUserBoot(UserStartedState uss) {
17103        synchronized (this) {
17104            if (uss.mState == UserStartedState.STATE_BOOTING
17105                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17106                uss.mState = UserStartedState.STATE_RUNNING;
17107                final int userId = uss.mHandle.getIdentifier();
17108                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17109                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17110                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17111                broadcastIntentLocked(null, null, intent,
17112                        null, null, 0, null, null,
17113                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17114                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17115            }
17116        }
17117    }
17118
17119    void finishUserSwitch(UserStartedState uss) {
17120        synchronized (this) {
17121            finishUserBoot(uss);
17122
17123            startProfilesLocked();
17124
17125            int num = mUserLru.size();
17126            int i = 0;
17127            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17128                Integer oldUserId = mUserLru.get(i);
17129                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17130                if (oldUss == null) {
17131                    // Shouldn't happen, but be sane if it does.
17132                    mUserLru.remove(i);
17133                    num--;
17134                    continue;
17135                }
17136                if (oldUss.mState == UserStartedState.STATE_STOPPING
17137                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17138                    // This user is already stopping, doesn't count.
17139                    num--;
17140                    i++;
17141                    continue;
17142                }
17143                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17144                    // Owner and current can't be stopped, but count as running.
17145                    i++;
17146                    continue;
17147                }
17148                // This is a user to be stopped.
17149                stopUserLocked(oldUserId, null);
17150                num--;
17151                i++;
17152            }
17153        }
17154    }
17155
17156    @Override
17157    public int stopUser(final int userId, final IStopUserCallback callback) {
17158        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17159                != PackageManager.PERMISSION_GRANTED) {
17160            String msg = "Permission Denial: switchUser() from pid="
17161                    + Binder.getCallingPid()
17162                    + ", uid=" + Binder.getCallingUid()
17163                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17164            Slog.w(TAG, msg);
17165            throw new SecurityException(msg);
17166        }
17167        if (userId <= 0) {
17168            throw new IllegalArgumentException("Can't stop primary user " + userId);
17169        }
17170        synchronized (this) {
17171            return stopUserLocked(userId, callback);
17172        }
17173    }
17174
17175    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17176        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17177        if (mCurrentUserId == userId) {
17178            return ActivityManager.USER_OP_IS_CURRENT;
17179        }
17180
17181        final UserStartedState uss = mStartedUsers.get(userId);
17182        if (uss == null) {
17183            // User is not started, nothing to do...  but we do need to
17184            // callback if requested.
17185            if (callback != null) {
17186                mHandler.post(new Runnable() {
17187                    @Override
17188                    public void run() {
17189                        try {
17190                            callback.userStopped(userId);
17191                        } catch (RemoteException e) {
17192                        }
17193                    }
17194                });
17195            }
17196            return ActivityManager.USER_OP_SUCCESS;
17197        }
17198
17199        if (callback != null) {
17200            uss.mStopCallbacks.add(callback);
17201        }
17202
17203        if (uss.mState != UserStartedState.STATE_STOPPING
17204                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17205            uss.mState = UserStartedState.STATE_STOPPING;
17206            updateStartedUserArrayLocked();
17207
17208            long ident = Binder.clearCallingIdentity();
17209            try {
17210                // We are going to broadcast ACTION_USER_STOPPING and then
17211                // once that is done send a final ACTION_SHUTDOWN and then
17212                // stop the user.
17213                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17214                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17215                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17216                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17217                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17218                // This is the result receiver for the final shutdown broadcast.
17219                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17220                    @Override
17221                    public void performReceive(Intent intent, int resultCode, String data,
17222                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17223                        finishUserStop(uss);
17224                    }
17225                };
17226                // This is the result receiver for the initial stopping broadcast.
17227                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17228                    @Override
17229                    public void performReceive(Intent intent, int resultCode, String data,
17230                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17231                        // On to the next.
17232                        synchronized (ActivityManagerService.this) {
17233                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17234                                // Whoops, we are being started back up.  Abort, abort!
17235                                return;
17236                            }
17237                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17238                        }
17239                        mSystemServiceManager.stopUser(userId);
17240                        broadcastIntentLocked(null, null, shutdownIntent,
17241                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17242                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17243                    }
17244                };
17245                // Kick things off.
17246                broadcastIntentLocked(null, null, stoppingIntent,
17247                        null, stoppingReceiver, 0, null, null,
17248                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17249                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17250            } finally {
17251                Binder.restoreCallingIdentity(ident);
17252            }
17253        }
17254
17255        return ActivityManager.USER_OP_SUCCESS;
17256    }
17257
17258    void finishUserStop(UserStartedState uss) {
17259        final int userId = uss.mHandle.getIdentifier();
17260        boolean stopped;
17261        ArrayList<IStopUserCallback> callbacks;
17262        synchronized (this) {
17263            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17264            if (mStartedUsers.get(userId) != uss) {
17265                stopped = false;
17266            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17267                stopped = false;
17268            } else {
17269                stopped = true;
17270                // User can no longer run.
17271                mStartedUsers.remove(userId);
17272                mUserLru.remove(Integer.valueOf(userId));
17273                updateStartedUserArrayLocked();
17274
17275                // Clean up all state and processes associated with the user.
17276                // Kill all the processes for the user.
17277                forceStopUserLocked(userId, "finish user");
17278            }
17279        }
17280
17281        for (int i=0; i<callbacks.size(); i++) {
17282            try {
17283                if (stopped) callbacks.get(i).userStopped(userId);
17284                else callbacks.get(i).userStopAborted(userId);
17285            } catch (RemoteException e) {
17286            }
17287        }
17288
17289        if (stopped) {
17290            mSystemServiceManager.cleanupUser(userId);
17291            synchronized (this) {
17292                mStackSupervisor.removeUserLocked(userId);
17293            }
17294        }
17295    }
17296
17297    @Override
17298    public UserInfo getCurrentUser() {
17299        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17300                != PackageManager.PERMISSION_GRANTED) && (
17301                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17302                != PackageManager.PERMISSION_GRANTED)) {
17303            String msg = "Permission Denial: getCurrentUser() from pid="
17304                    + Binder.getCallingPid()
17305                    + ", uid=" + Binder.getCallingUid()
17306                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17307            Slog.w(TAG, msg);
17308            throw new SecurityException(msg);
17309        }
17310        synchronized (this) {
17311            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17312        }
17313    }
17314
17315    int getCurrentUserIdLocked() {
17316        return mCurrentUserId;
17317    }
17318
17319    @Override
17320    public boolean isUserRunning(int userId, boolean orStopped) {
17321        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17322                != PackageManager.PERMISSION_GRANTED) {
17323            String msg = "Permission Denial: isUserRunning() from pid="
17324                    + Binder.getCallingPid()
17325                    + ", uid=" + Binder.getCallingUid()
17326                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17327            Slog.w(TAG, msg);
17328            throw new SecurityException(msg);
17329        }
17330        synchronized (this) {
17331            return isUserRunningLocked(userId, orStopped);
17332        }
17333    }
17334
17335    boolean isUserRunningLocked(int userId, boolean orStopped) {
17336        UserStartedState state = mStartedUsers.get(userId);
17337        if (state == null) {
17338            return false;
17339        }
17340        if (orStopped) {
17341            return true;
17342        }
17343        return state.mState != UserStartedState.STATE_STOPPING
17344                && state.mState != UserStartedState.STATE_SHUTDOWN;
17345    }
17346
17347    @Override
17348    public int[] getRunningUserIds() {
17349        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17350                != PackageManager.PERMISSION_GRANTED) {
17351            String msg = "Permission Denial: isUserRunning() from pid="
17352                    + Binder.getCallingPid()
17353                    + ", uid=" + Binder.getCallingUid()
17354                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17355            Slog.w(TAG, msg);
17356            throw new SecurityException(msg);
17357        }
17358        synchronized (this) {
17359            return mStartedUserArray;
17360        }
17361    }
17362
17363    private void updateStartedUserArrayLocked() {
17364        int num = 0;
17365        for (int i=0; i<mStartedUsers.size();  i++) {
17366            UserStartedState uss = mStartedUsers.valueAt(i);
17367            // This list does not include stopping users.
17368            if (uss.mState != UserStartedState.STATE_STOPPING
17369                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17370                num++;
17371            }
17372        }
17373        mStartedUserArray = new int[num];
17374        num = 0;
17375        for (int i=0; i<mStartedUsers.size();  i++) {
17376            UserStartedState uss = mStartedUsers.valueAt(i);
17377            if (uss.mState != UserStartedState.STATE_STOPPING
17378                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17379                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17380                num++;
17381            }
17382        }
17383    }
17384
17385    @Override
17386    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17387        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17388                != PackageManager.PERMISSION_GRANTED) {
17389            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17390                    + Binder.getCallingPid()
17391                    + ", uid=" + Binder.getCallingUid()
17392                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17393            Slog.w(TAG, msg);
17394            throw new SecurityException(msg);
17395        }
17396
17397        mUserSwitchObservers.register(observer);
17398    }
17399
17400    @Override
17401    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17402        mUserSwitchObservers.unregister(observer);
17403    }
17404
17405    private boolean userExists(int userId) {
17406        if (userId == 0) {
17407            return true;
17408        }
17409        UserManagerService ums = getUserManagerLocked();
17410        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17411    }
17412
17413    int[] getUsersLocked() {
17414        UserManagerService ums = getUserManagerLocked();
17415        return ums != null ? ums.getUserIds() : new int[] { 0 };
17416    }
17417
17418    UserManagerService getUserManagerLocked() {
17419        if (mUserManager == null) {
17420            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17421            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17422        }
17423        return mUserManager;
17424    }
17425
17426    private int applyUserId(int uid, int userId) {
17427        return UserHandle.getUid(userId, uid);
17428    }
17429
17430    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17431        if (info == null) return null;
17432        ApplicationInfo newInfo = new ApplicationInfo(info);
17433        newInfo.uid = applyUserId(info.uid, userId);
17434        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17435                + info.packageName;
17436        return newInfo;
17437    }
17438
17439    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17440        if (aInfo == null
17441                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17442            return aInfo;
17443        }
17444
17445        ActivityInfo info = new ActivityInfo(aInfo);
17446        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17447        return info;
17448    }
17449
17450    private final class LocalService extends ActivityManagerInternal {
17451        @Override
17452        public void goingToSleep() {
17453            ActivityManagerService.this.goingToSleep();
17454        }
17455
17456        @Override
17457        public void wakingUp() {
17458            ActivityManagerService.this.wakingUp();
17459        }
17460    }
17461
17462    /**
17463     * An implementation of IAppTask, that allows an app to manage its own tasks via
17464     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17465     * only the process that calls getAppTasks() can call the AppTask methods.
17466     */
17467    class AppTaskImpl extends IAppTask.Stub {
17468        private int mTaskId;
17469        private int mCallingUid;
17470
17471        public AppTaskImpl(int taskId, int callingUid) {
17472            mTaskId = taskId;
17473            mCallingUid = callingUid;
17474        }
17475
17476        @Override
17477        public void finishAndRemoveTask() {
17478            // Ensure that we are called from the same process that created this AppTask
17479            if (mCallingUid != Binder.getCallingUid()) {
17480                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17481                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17482                return;
17483            }
17484
17485            synchronized (ActivityManagerService.this) {
17486                long origId = Binder.clearCallingIdentity();
17487                try {
17488                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17489                    if (tr != null) {
17490                        // Only kill the process if we are not a new document
17491                        int flags = tr.getBaseIntent().getFlags();
17492                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17493                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17494                        removeTaskByIdLocked(mTaskId,
17495                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17496                    }
17497                } finally {
17498                    Binder.restoreCallingIdentity(origId);
17499                }
17500            }
17501        }
17502
17503        @Override
17504        public ActivityManager.RecentTaskInfo getTaskInfo() {
17505            // Ensure that we are called from the same process that created this AppTask
17506            if (mCallingUid != Binder.getCallingUid()) {
17507                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17508                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17509                return null;
17510            }
17511
17512            synchronized (ActivityManagerService.this) {
17513                long origId = Binder.clearCallingIdentity();
17514                try {
17515                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17516                    if (tr != null) {
17517                        return createRecentTaskInfoFromTaskRecord(tr);
17518                    }
17519                } finally {
17520                    Binder.restoreCallingIdentity(origId);
17521                }
17522                return null;
17523            }
17524        }
17525    }
17526}
17527